Git Product home page Git Product logo

resolve-typescript-plugin's Introduction

resolve-typescript-plugin

A webpack plugin to resolve TypeScript files imported using the .js extension when using ESM imports.

Obsolete

webpack has equivalent functionality built-in since v5.74.0. This plugin is no longer needed unless you are using an older version of webpack.

To migrate from this plugin, set resolve.extensionAlias in webpack.config.js:

export default {
    resolve: {
        extensionAlias: {
            ".js": [".ts", ".js"],
            ".mjs": [".mts", ".mjs"]
        }
    }
};

and remove new ResolveTypeScriptPlugin() from resolve.plugins.

For the time being this plugin is still maintained for the benefit of people who use older versions of webpack.

Why?

If you are using webpack in conjunction with TypeScript and ES Modules, you need this plugin for full compliance with the ES Modules ecosystem.

ES Modules require imports to specify the runtime path of the file to be imported, including file extension. For TypeScript files, this means that you must import using the extension .js even though the source file uses the extension .ts or .tsx. This is because TypeScript compiles to a .js file that will be used at runtime.

However, webpack behaves differently, even when configured for ES Modules. webpack expects that files will be imported by specifying the compile-time path of the file, including the compile-time extension. For TypeScript files this will be .ts or .tsx. Alternatively, webpack expects that files will be imported with no extension, in which case webpack will resolve the extension automatically according to the resolve.extensions option. Neither of these behaviours is consistent with browser or node ES Module environments.

This plugin extends webpack module resolution so that imports specifying a .js extension will resolve to the corresponding .ts or .tsx file if available, and fall back to .js otherwise.

If you want to create ES Modules in TypeScript that are consistent between webpack, browser, and node environments, use this plugin.

See ts-loader#1110 for more background on this issue.

Install

With npm:

npm install --save-dev resolve-typescript-plugin

or yarn:

yarn add --dev resolve-typescript-plugin

Usage

Include the following in package.json to configure your project to be an ES Module:

{
    "type": "module"
}

Include something like the following in webpack.config.js:

import ResolveTypeScriptPlugin from "resolve-typescript-plugin";

export default {
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: "ts-loader"
            }
        ]
    },
    resolve: {
        plugins: [new ResolveTypeScriptPlugin()]
    }
};

You will also need to have ts-loader (or another TypeScript loader) installed and configured.

Previous versions of this README recommended setting resolve.fullySpecified to true. This is no longer recommended because it breaks compatibility with webpack-dev-server and possibly other webpack tooling.

If you use this plugin, you should probably remove .ts and .tsx from resolve.extensions.

Options

Pass options to the plugin as an argument to the constructor, as follows:

new ResolveTypeScriptPlugin({
    includeNodeModules: false
});

includeNodeModules

By default, the plugin does not resolve TypeScript files inside node_modules subdirectories. To enable this, set includeNodeModules: true.

Default: false.

Webpack 4 Compatibility

This plugin supports webpack versions 4.x and 5.x. However, there are some caveats when using webpack 4.x in conjunction with ES modules.

Webpack 4.x does not support webpack.config files in ES module format, so if you set "type": "module" in package.json then you must mark the webpack.config file as a CommonJS file by naming it webpack.config.cjs (with a .cjs extension). Of course, you must also use CommonJS format, for example:

const ResolveTypeScriptPlugin = require("resolve-typescript-plugin");

module.exports = {
    module: {
        rules: [
            {
                test: /\.tsx?$/,
                use: "ts-loader"
            }
        ]
    },
    resolve: {
        plugins: [new ResolveTypeScriptPlugin()]
    }
};

Webpack 4.x also will not discover the webpack.config file automatically if it is named with a .cjs extension, so you must specify the path to the configuration file explicitly when running webpack, for example: webpack --config ./webpack.config.cjs.

Webpack 5.x has none of these caveats. In Webpack 5.x, configuration files may be in ES Module or CommonJS format, and will be discovered automatically if they are named with any of .js, .cjs, or .mjs file extensions.

Feedback

Please report bugs, problems, and missing features on the GitHub Issue Tracker.

resolve-typescript-plugin's People

Contributors

dependabot[bot] avatar djcsdy avatar jacobmischka avatar renovate-bot avatar renovate[bot] avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

resolve-typescript-plugin's Issues

Does not work with webpack 4

would like to use this plugin in storybook, I've got a local version of this plugin working with storybook + webpack 5, but when using webpack 4, it fails to compile.

typo error in doc

resolve: {
        fullySpecfied: true,
        plugins: [new ResolveTypeScriptPlugin()]
    }
}

fullySpecfied should be changed to fullySpecified

Seeking community feedback on this plugin

This plugin works by inserting itself into the resolution process, and whenever webpack is resolving a file ending in .js, the plugin tries .ts and then .tsx first, and then continues with the usual process if those files don't exist. This plugin ignores files within node_modules so those files are resolved as normal with no alteration to the file extension.

I'm not sure of my approach and I'm seeking community feedback, so if anyone interested in this problem could take a look and let me know what they think I'd really appreciate it.

In particular:

  • Should this solution, or something like it, be rolled into another project such as ts-loader, enhanced-resolve, or webpack itself? I'm interested in helping with this if so. Opinions of the maintainers of those projects are especially welcome :-).
  • Am I hooking into enhanced-resolve in the right place? There are lots of places I could hook in to do this and it's not clear if the one I've chosen is the best choice.
  • Is there a better way to skip files from external libraries (e.g. files from node_modules)? At the moment the plugin skips over any request where node_modules appears as a part of the path, but I'm not really happy with this. Apart from being a hack, the current solution has the obvious problem that it doesn't work if external libraries are in a directory other than node_modules, and it doesn't work if the project you're building is itself in a node_modules hierarchy (I can imagine use cases for doing this). Ideally I think I'd like to ignore any request that has passed through ModulesInHierachicDirectoriesPlugin at any point, but I can't see a good way to do this.
  • Is skipping imports from external libraries even a good idea? My rationale for skipping external files is that some library developers might distribute .ts files on npm in addition to the compiled .js files, for use with source maps, and it's desirable for webpack to resolve the .js files and not the .ts files in this case. TypeScript itself won't compile source files resolved from node_modules when you compile with tsc.

Test projects recursively copy themselves into node_modules

The test projects depend on resolve-typescript-plugin like this:

    "resolve-typescript-plugin": "../..",

This causes each test-project to copy itself and all the other test projects into its own node_modules. This compounds over time, so each successive yarn install within a test project takes longer than the last.

Find a better way to do this.

perf: Register fewer hooks

@djcsdy Yep, anyway we can improve perf more, we don't need to rewrite it for all extensions https://github.com/softwareventures/resolve-typescript-plugin/blob/main/index.ts#L28, only for ts/cts/mts, so we can add test regexp check, you try to solve it using node_modules regexp because most of js inside there, but JS can be not only in node_modules

You register two hooks https://github.com/softwareventures/resolve-typescript-plugin/blob/main/index.ts#L24, it can be bad for perf if you have a lot of ts files, better to improve regexp and use only one hook

TypeStrong/ts-loader#1383 (comment)

Provide a ESM export?

When using this plugin inside of a webpack.config.ts I have to do something along the lines of

import _ResolveTypeScriptPlugin from 'resolve-typescript-plugin';
// @ts-ignore
const ResolveTypeScriptPlugin = _ResolveTypeScriptPlugin.default;

as doing both

import ResolveTypeScriptPlugin from 'resolve-typescript-plugin'; and
import * as ResolveTypeScriptPlugin from 'resolve-typescript-plugin'; result in

[webpack-cli] Failed to load '/home/cobertos/Seafile/projects/mapcast/monorepo/pkg/app-auctions/webpack.config.ts' config
[webpack-cli] webpack.config.ts:85:19 - error TS2351: This expression is not constructable.
  Type 'typeof import("/home/cobertos/Seafile/projects/mapcast/monorepo/node_modules/resolve-typescript-plugin/index")' has no construct signatures.

85     plugins: [new ResolveTypeScriptPlugin()]
                     ~~~~~~~~~~~~~~~~~~~~~~~

I think this is because the built index.js is using?

Object.defineProperty(exports, "__esModule", { value: true });
//...
exports.default = ResolveTypescriptPlugin;

instead of commonjs module.exports or ESM export default ....

Run npm deprecate on this package

Just a suggestion but even your own readme does state this package is obsolete at this time. While it does seem the tail dropped off pretty hard in your weekly download stats, it might not be a bad idea to push it a bit further and run npm deprecate resolve-typescript-plugin "Use resolve.extensionAlias in webpack.config.js instead"

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.