I'm adding TypeScript to the build process of a currently all-JavaScript web app whose build process is structured around Webpack. I've been following TypeScript's Migrating from JavaScript article, and have a question about the suggested Webpack configuration¹, copied below for your convenience:
module.exports = {
entry: "./src/index.ts",
output: {
filename: "./dist/bundle.js",
},
// Enable sourcemaps for debugging webpack's output.
devtool: "source-map",
resolve: {
// Add '.ts' and '.tsx' as resolvable extensions.
extensions: ["", ".webpack.js", ".web.js", ".ts", ".tsx", ".js"]
},
module: {
loaders: [
// All files with a '.ts' or '.tsx' extension will be handled by 'awesome-typescript-loader'.
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" }
],
preLoaders: [
// All output '.js' files will have any sourcemaps re-processed by 'source-map-loader'.
{ test: /\.js$/, loader: "source-map-loader" }
]
},
// Other options...
};
The presence of awesome-typescript-loader
is of course required — we want to compile TypeScript, after all. My question is about source-map-loader
, used here as a pre-loader. The article is pretty terse about its purpose, saying only:
You can use
awesome-typescript-loader
, a TypeScript loader, combined withsource-map-loader
for easier debugging.
Another article adds only a bit of extra information:
Both of these dependencies will let TypeScript and Webpack play well together.
awesome-typescript-loader
helps Webpack compile your TypeScript code using the TypeScript’s standard configuration file namedtsconfig.json
.source-map-loader
uses any sourcemap outputs from TypeScript to inform webpack when generating its own sourcemaps. This will allow you to debug your final output file as if you were debugging your original TypeScript source code.
Finally, source-map-loader
's own README says:
source-map-loader extracts
existing source maps from all JavaScript entries. This includes both inline source maps as well as those linked via URL. All source map data is passed to webpack for processing as per a chosen source map style specified by the devtool option inwebpack.config.js
.
Ok. So source-map-loader
ingests source maps and provides them to Webpack. My question, though, is why should it be running as a pre-loader? Based on the second quote, above, it sounds like source-map-loader
is supposed to pick up sourcemap outputs from TypeScript. If it runs as a pre-loader, though, it runs before normal loaders, and I don't understand how it can use output from TypeScript.
Further, I was under the impression that Webpack doesn't deal with intermediate files — in the configuration, source-map-loader
only loads .jsx?
files. Doesn't that mean source-map-loader
won't be invoked on the results of TypeScript compilation at all?
1: Note that this Webpack configuration uses outdated syntax, listing normal loaders in the module.loaders
section, and pre-loaders in the module.preLoaders
section. This doesn't affect the content of this question, and an example with current syntax is available at a similar article from the same site.
source-map-loader allows webpack to maintain source map data continuity across libraries so ease of debugging is preserved. The source-map-loader will extract from any JavaScript file, including those in the node_modules directory.
Enabling source maps in webpackgenerateSourceMaps({ type: "source-map" }), ]); source-map is the slowest and highest quality option of them all, but that's fine for a production build. If you build the project now ( npm run build ), you should see source maps in the project output at the dist directory.
In a sense, source maps are the decoder ring to your secret (minified) code. Using Webpack, specifying devtool: "source-map" in your Webpack config will enable source maps, and Webpack will output a sourceMappingURL directive in your final, minified file.
Normally in a typescript project you have a tsconfig. json file, which is used with the tsc npm command to compile the project into javascript. With webpack however the project is compiled, without tsc being installed.
It doesn't have anything to do with TypeScript compilation per se, and you don't need it to get source maps to work for your own sources. However, you probably want it for the following reason, as mentioned in the paragraph right after the one you quoted from source-map-loader
's README:
This loader is especially useful when using 3rd-party libraries having their own source maps. If not extracted and processed into the source map of the webpack bundle, browsers may misinterpret source map data. source-map-loader allows webpack to maintain source map data continuity across libraries so ease of debugging is preserved.
The reason it's a preloader is because it has to be run on .js
files before they are minified, since that tends to remove inline source maps. Since it only reacts on .js
files and not .ts
files it isn't run before your TypeScript files are transpiled, but right after they have been outputted to .js
files.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With