Оптимизация продолжительности сборки приложения Angular 2 с помощью webpack
Я создаю приложение Angular 2 и связываю его с webpack. На данный момент мое приложение все еще мало, но задача webpack уже занимает около 10 секунд. Можно ли оптимизировать конфигурацию webpack или параметры компиляции TypeSript для улучшения продолжительности компиляции и упаковки ?
это конфигурация webpack, которую я использую:
var webpack = require('webpack');
var LiveReloadPlugin = require('webpack-livereload-plugin');
module.exports = {
entry: __dirname + '/assets/app/app.ts',
output: {
filename: 'myApp.bundle.js',
path: __dirname + '/build/'
},
// Turn on sourcemaps
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new LiveReloadPlugin({
appendScriptTag: true
}),
// Fixes angular 2 warning
new webpack.ContextReplacementPlugin(
/angular(|/)core(|/)(esm(|/)src|src)(|/)linker/,
__dirname
)
],
module: {
rules: [{
enforce: 'pre',
test: /.js$/,
loader: "source-map-loader"
},
{
enforce: 'pre',
test: /.tsx?$/,
use: "ts-loader"
}
]
}
}
и tsconfig :
{
"compilerOptions": {
"target": "ES5",
"module": "commonjs",
"moduleResolution": "node",
"sourceMap": true,
"pretty": true,
"emitDecoratorMetadata": true,
"experimentalDecorators": true,
"noUnusedLocals": false,
"removeComments": true,
"skipLibCheck": true,
"strictNullChecks": false,
"baseUrl": "./src",
"typeRoots": ["node_modules/@types"],
"types": [
"core-js",
"systemjs"
],
"outDir": "./build"
},
"exclude": [
"node_modules"
]
}
обновление (см. Мой ответ на фиксированный webpack.config)
Я попробую плагин DLL webpack, предложенный @jpwiddy, путем компиляции angular в отдельной сборке, чтобы перестроить только код приложения во время разработки и получить значительное время компиляции.
однако после проверки выходного JS размер файла остается прежним, и внутри все еще есть угловой код.
вот новый файл конфигурации webpack для угловых источников :
var webpack = require('webpack');
module.exports = {
entry: {
angular:[
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/core',
'@angular/common',
'@angular/compiler',
'@angular/http',
'@angular/router',
'@angular/forms'
]
},
output: {
filename: 'ng2.dll.js',
path: __dirname + '/build/',
library: 'ng2'
},
plugins: [
// Fixes angular 2 warning
new webpack.ContextReplacementPlugin(
/angular(|/)core(|/)(esm(|/)src|src)(|/)linker/,
__dirname
),
new webpack.DllPlugin({
name: 'ng2',
path: __dirname + '/build/ng2.json'
})
]
}
и обновленная конфигурация webpack для приложения:
var webpack = require('webpack');
var LiveReloadPlugin = require('webpack-livereload-plugin');
module.exports = {
entry: __dirname + '/assets/app/app.ts',
output: {
filename: 'myApp.bundle.js',
path: __dirname + '/build/'
},
// Turn on sourcemaps
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new LiveReloadPlugin({
appendScriptTag: true
}),
// Fixes angular 2 warning
new webpack.ContextReplacementPlugin(
/angular(|/)core(|/)(esm(|/)src|src)(|/)linker/,
__dirname
),
new webpack.DllReferencePlugin({
context: __dirname + '/build/',
manifest: require(__dirname + '/build/ng2.json')
})
],
module: {
rules: [{
enforce: 'pre',
test: /.js$/,
loader: "source-map-loader"
},
{
enforce: 'pre',
test: /.tsx?$/,
use: "ts-loader"
}
]
}
}
вот один из углового кода, который я нашел в моем приложении JS output:
_TsEmitterVisitor.prototype.visitBuiltintType = function (type, ctx) {
var typeStr;
switch (type.name) {
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].Bool:
typeStr = 'boolean';
break;
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].Dynamic:
typeStr = 'any';
break;
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].Function:
typeStr = 'Function';
break;
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].Number:
typeStr = 'number';
break;
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].Int:
typeStr = 'number';
break;
case __WEBPACK_IMPORTED_MODULE_2__output_ast__["R" /* BuiltinTypeName */].String:
typeStr = 'string';
break;
default:
throw new Error("Unsupported builtin type " + type.name);
}
ctx.print(typeStr);
return null;
};
я пропустил что-то в новой конфигурации, чтобы предотвратить webpack, включая угловые источники в выходе ?
спасибо
2 ответов
один отличный способ, который я лично сделал, ускорил процесс сборки Webpack, - это реализация DLL в вашей сборке.
Webpack работает, анализируя ваш код для require
s и import
s, а затем строит таблицу из этих операторов всех ваших зависимостей модуля и ссылок на то, где эти файлы можно найти.
плагин DLL улучшает это, так как при регистрации зависимостей с DLL каждый раз, когда эти зависимости меняются (должно быть очень нечасто), вы создаете DLL (состоящую из пакета javascript и файла манифеста JSON) и обертываете все эти зависимости в один пакет. Этот пакет затем ссылается при вытягивании этих зависимостей в приложение.
небольшой пример:
entry: {
angular:[
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/core',
'@angular/common',
'@angular/compiler',
'@angular/http',
'@angular/router',
'@angular/forms'
],
bs: [
'bootstrap',
'ng-bootstrap'
]
},
output: {
filename: '[name].dll.js',
path: outputPath,
library: '[name]',
},
plugins: [
new webpack.DllPlugin({
name: '[name]',
path: join(outputPath, '[name].json')
})
]
... а потом ссылались как так -
{
plugins: [
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(join(outputPath, 'angular.json'))
}),
new webpack.DllReferencePlugin({
context: process.cwd(),
manifest: require(join(outputPath, 'bs.json'))
}),
]
}
мне удалось исправить мою конфигурацию с помощью нового модуля webpack-dll-пакеты-плагин (который использует DllPlugin и DllReferencePlugin в фоновом режиме) делает именно то, что я искал : изолируя сборку Angular 2 в своем собственном пакете и избегая перестройки всего моего пакета каждый раз, когда я хочу перестроить свой код приложения (например, с наблюдателем).
мое время восстановления упало с 10 секунд до 1 секунды.
вот мой новый webpack config:
var webpack = require('webpack');
var LiveReloadPlugin = require('webpack-livereload-plugin');
const DllBundlesPlugin = require('webpack-dll-bundles-plugin').DllBundlesPlugin;
module.exports = {
entry: __dirname + '/assets/app/app.ts',
output: {
filename: 'myApp.bundle.js',
path: __dirname + '/build/'
},
// Turn on sourcemaps
devtool: 'source-map',
resolve: {
extensions: ['.ts', '.js']
},
plugins: [
new LiveReloadPlugin({
appendScriptTag: true
}),
// Fixes angular 2 warning
new webpack.ContextReplacementPlugin(
/angular(\|\/)core(\|\/)(esm(\|\/)src|src)(\|\/)linker/,
__dirname
),
new DllBundlesPlugin({
bundles: {
vendor: [
'@angular/platform-browser',
'@angular/platform-browser-dynamic',
'@angular/core',
'@angular/common',
'@angular/forms',
'@angular/http',
'@angular/router',
'rxjs',
]
},
dllDir: __dirname + '/build/',
webpackConfig: {}
})
],
module: {
rules: [{
enforce: 'pre',
test: /\.js$/,
loader: "source-map-loader"
},
{
enforce: 'pre',
test: /\.tsx?$/,
use: "ts-loader"
}
]
}
}