webpack - Hvorfor kompilere ikke ts-loader min TypeScript?
Jeg prøver å bruke Webpack for å kompilere noe TypeScript ved hjelp av ts-loader, men det kjører ikke tsc slik jeg forventer. Hvis jeg gjør endringer i en ts-fil, kompilerer ikke webpack den tilbake til js, det samme skjer hvis jeg sletter den genererte js-filen helt og kjører webpack på nytt.
Typescript er satt opp fint fordi jeg kan kjøre ./node_modules/typescript/bin/tsc og det genererer js-filene helt fint. Har jeg rett i å tro at ts-loader bare skal kjøre tsc mot min tsconfig.json? Hvis ja, hvorfor oppdager det ikke endringer og genererer js-en min som forventet?
Som du kan se, er inngangspunktet mitt ./Client/boot-client.ts og ikke engang dette blir kompilert når jeg kjører gjennom webpack.
Den spesifikke webpack-kommandoen jeg kjører er:
./node_modules/webpack/bin/webpack.js --progressSom gir følgende utdata
[0] building modulests-loader: Using [email and C:\git\coliver\couchtrace\Couchtrace.Web\tsconfig.json
[1] building modulests-loader: Using [email and C:\git\coliver\couchtrace\Couchtrace.Web\tsconfig.json
[1] Hash: 568887199c9c2bcbe47ec00669704990969dbee5
Version: webpack 2.3.2
Child
Hash: 568887199c9c2bcbe47e
Time: 20096ms
Asset Size Chunks Chunk Names
main-client.js 554 kB 0 [emitted] [big] main-client
main-client.js.map 859 kB 0 [emitted] main-client
[0] delegated ./node_modules/rxjs/Observable.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[5] delegated ./node_modules/rxjs/Subject.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[14] delegated ./node_modules/@angular/core/index.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[19] ./~/rxjs/AsyncSubject.js 1.6 kB {0} [built]
[20] ./~/rxjs/ReplaySubject.js 2.99 kB {0} [built]
[33] delegated ./node_modules/angular2-universal/browser/index.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[34] ./~/rxjs/add/operator/map.js 156 bytes {0} [built]
[60] ./Client/src/app.module.ts 1.86 kB {0} [built]
[61] delegated ./node_modules/angular2-universal-polyfills/browser.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[68] ./~/rxjs/Rx.js 9.61 kB {0} [built]
[180] ./~/rxjs/add/operator/takeUntil.js 186 bytes {0} [built]
[335] ./Client/boot-client.ts 951 bytes {0} [built]
[344] delegated ./node_modules/rxjs/symbol/rxSubscriber.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[351] delegated ./node_modules/rxjs/util/ObjectUnsubscribedError.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
[353] delegated ./node_modules/@angular/router/index.js from dll-reference vendor_c9f874e7c2f104739cd8 42 bytes {0} [not cacheable] [built]
+ 345 hidden modules
Child
Hash: c00669704990969dbee5
Time: 20085ms
Asset Size Chunks Chunk Names
main-server.js 552 kB 0 [emitted] [big] main-server
[5] delegated ./node_modules/rxjs/Subject.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[14] delegated ./node_modules/@angular/core/bundles/core.umd.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[19] ./~/rxjs/AsyncSubject.js 1.6 kB {0} [built]
[20] ./~/rxjs/ReplaySubject.js 2.99 kB {0} [built]
[21] ./~/rxjs/util/ArgumentOutOfRangeError.js 974 bytes {0} [built]
[32] delegated ./node_modules/angular2-universal/node/index.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[53] delegated ./node_modules/rxjs/add/operator/map.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[59] ./Client/src/app.module.ts 1.86 kB {0} [built]
[60] delegated ./node_modules/zone.js/dist/zone-node.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[61] delegated ./node_modules/angular2-universal-polyfills/node.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[62] delegated ./node_modules/aspnet-prerendering/index.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[69] ./~/rxjs/Rx.js 9.61 kB {0} [built]
[336] ./Client/boot-server.ts 1.37 kB {0} [built]
[356] delegated ./node_modules/rxjs/symbol/rxSubscriber.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
[360] delegated ./node_modules/@angular/router/bundles/router.umd.js from dll-reference ./vendor 42 bytes {0} [not cacheable] [built]
+ 346 hidden modules
Versjoner
- webpack: 2.3.2
- ts-loader: 2.0.3
- typescript: 2.2.2
webpack.config.js
var isDevBuild = process.argv.indexOf('--env.prod') < 0;
var path = require('path');
var webpack = require('webpack');
var merge = require('webpack-merge');
// Configuration in common to both client-side and server-side bundles
var sharedConfig = {
context: __dirname,
resolve: { extensions: [ '.ts', '.js' ] },
output: {
filename: '[name].js',
// publicPath: '/dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
},
module: {
rules: [
{ test: /\.js$/, enforce: 'pre', use: 'source-map-loader' },
{ test: /\.ts$/, enforce: 'pre', use: 'source-map-loader' },
{ test: /\.ts$/, use: ['ts-loader', 'angular2-template-loader'], exclude: /node_modules/ },
{ test: /\.html$/, use: 'html-loader?minimize=false' },
{ test: /\.css$/, use: ['to-string-loader','css-loader'] },
{ test: /\.(png|jpg|jpeg|gif|svg)$/, loader: 'url-loader', query: { limit: 25000 } },
{ test: /\.json$/, use: 'json-loader' }
]
}
};
// Configuration for client-side bundle suitable for running in browsers
var clientBundleOutputDir = './wwwroot/dist';
var clientBundleConfig = merge(sharedConfig, {
entry: { 'main-client': './Client/boot-client.ts' },
output: { path: path.join(__dirname, clientBundleOutputDir) },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./wwwroot/dist/vendor-manifest.json')
})
].concat(isDevBuild ? [
// Plugins that apply in development builds only
new webpack.SourceMapDevToolPlugin({
filename: '[file].map', // Remove this line if you prefer inline source maps
moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
})
] : [
// Plugins that apply in production builds only
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.optimize.UglifyJsPlugin()
]),
target: 'web',
devtool: 'inline-source-map'
});
// Configuration for server-side (prerendering) bundle suitable for running in Node
var serverBundleConfig = merge(sharedConfig, {
resolve: { mainFields: ['main'] },
entry: { 'main-server': './Client/boot-server.ts' },
plugins: [
new webpack.DllReferencePlugin({
context: __dirname,
manifest: require('./Client/dist/vendor-manifest.json'),
sourceType: 'commonjs2',
name: './vendor'
})
],
output: {
libraryTarget: 'commonjs',
path: path.join(__dirname, './Client/dist')
},
target: 'node'
});
module.exports = [clientBundleConfig, serverBundleConfig];
tsconfig.json
{
"compilerOptions": {
"noImplicitAny": false,
"moduleResolution": "node",
"target": "es5",
"sourceMap": true,
"experimentalDecorators": true,
"emitDecoratorMetadata": true,
"skipDefaultLibCheck": true,
"lib": [ "es6", "dom" ],
"types": [ "node" ]
},
"exclude": [ "bin", "node_modules" ]
}
Svar #1
ts-loader skriver ikke noen filer til disken. Den kompilerer TypeScript-filene dine og overfører den resulterende JavaScripten til webpack, dette skjer i minnet. Det er ingen grunn til å skrive ut den kompilerte JavaScripten siden den er inkludert i bundlen. Bundlen inneholder alt du trenger.
Du kan se at ./Client/boot-client.ts kompileres (det betyr ikke at det skrives til disk) av følgende linje:
[335] ./Client/boot-client.ts 951 bytes {0} [built]
Svar #2
Etter å ha brukt en time eller to på det samme problemet, førte OPs spørsmål under Michael Jungos svar til en elegant løsning, så +1, Michael.
For å illustrere med et minimalt eksempel, gitt den følgende Webpack-konfigurasjonen:
let config = {
entry: {
'index': path.join(__dirname, 'index.ts')
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
},
module: {
rules: [
{
test: /\.(ts|tsx)$/,
exclude: /node_modules/,
use: [
{
loader: require.resolve('ts-loader')
}
]
}
]
}
};
Løsningen er i stedet å tillate Webpacks standard TypeScript-kompileringsadferd:
let config = {
entry: {
'index': path.join(__dirname, 'index.ts')
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, 'dist')
}
};
