Я пытаюсь разделить пакеты поставщика и приложения с помощью autodll-webpack-плагин (v0.4.2
). этот пакет является надстройкой верхнего уровня над DllPlugin webpack и добавить-актив-html-webpack-плагин для автоматического упорядочивания импорта в index.html
.
Этот плагин должен разделять библиотеки поставщиков и код приложения. Я мог бы сделать это с помощью CommonsChunkPlugin из webpack, но таким образом пакет восстанавливается при каждой перекомпиляции. Это менее эффективно, чем создание пакета поставщика один раз и его перекомпиляция только при изменении библиотеки.
Проблема
Я заставил этот плагин "работать" (он выводит vendor.bundle.js
). Единственная проблема здесь в том, что когда я проверяю app.bundle.js
с помощью веб-пакет-анализатор (v2.13.1
). Я вижу, что все node_modules, которые есть в vendor.bundle.js
, также загружены в этот пакет, поэтому плагин работает некорректно.
Версии
Я использую:
v4.11.0
v7.1.4
v6.26.3
v0.4.2
Структура проекта
Мой проект имеет следующую структуру документа:
App
-- build //Here are the output bundles located
-- node_modules
-- public
-- index.html
-- src // App code
-- webpack
-- webpack.common.js
-- webpack.dev.js
-- webpack.prod.js
-- package.json
Мой webpack.common.js (Этот код используется в сборках для разработчиков и разработчиков.)
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const AutoDllPlugin = require('autodll-webpack-plugin');
module.exports = {
entry: {
app: [
'babel-polyfill',
'./src/index.js',
],
},
output: {
filename: '[name].bundle.js',
path: path.resolve(__dirname, '../build'),
publicPath: '', // Is referenced by the autodll-webpack-plugin
},
module: {
rules: [
{
test: /\.jsx?$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
plugins: ['react-hot-loader/babel'],
cacheDirectory: true,
presets: ['env', 'react'],
},
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './public/index.html'
}),
new AutoDllPlugin({
inject: true, // will inject the DLL bundle to index.html
debug: false,
filename: '[name]_[hash].js',
context: path.join(__dirname, '..'),
path: '',
entry: {
vendor: [
'react',
'react-dom'
]
},
}),
],
};
Согласно документыautodll-webpack-plugin
контекстный ключ должен использоваться для разделения. Так что я думаю, что в этом проблема.
В документации описывается, что вы должны ссылаться на папку, в которой находится webpack.config.js
, но у меня их 3, на какую из них мне нужно ссылаться? И моя папка называется webpack
, а не config
, которую вы видите в документации, ..
здесь тоже правильный?
Так что в итоге я не смог заставить работать DLL. Прочитав еще немного, я понял, что создатель autodll-webpack-плагин советует вместо этого использовать жесткий-исходный-веб-пакет-плагин, потому что webpack, возможно, будет использовать его по умолчанию в будущем.
Прочитав еще немного, я также понял, что не рекомендуется использовать плагин DLL в производстве, так как вам все равно придется его перекомпилировать (сборка dev добавляет материал). Таким образом, вы должны использовать hard-source-webpack-plugin
для сборки разработчика и SplitChunksPlugin для производства.
Я заставил эти два работать довольно легко:
Webpack.dev.js
const merge = require('webpack-merge');
const webpack = require('webpack');
const path = require('path');
const HardSourceWebpackPlugin = require('hard-source-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'development',
devtool: 'eval-source-map',
devServer: {
hot: true,
contentBase: path.resolve(__dirname, 'build'),
historyApiFallback: true, // Allow refreshing of the page
},
plugins: [
// Enable hot reloading
new webpack.HotModuleReplacementPlugin(),
// Enable caching
new HardSourceWebpackPlugin({
cacheDirectory: '.cache/hard-source/[confighash]',
configHash: function(webpackConfig) {
return require('node-object-hash')({ sort: false }).hash(webpackConfig);
},
environmentHash: {
root: process.cwd(),
directories: [],
files: ['package-lock.json'],
},
info: {
mode: 'none',
level: 'warn',
},
}),
],
});
webpack.prod.js
const merge = require('webpack-merge');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const CleanWebpackPlugin = require('clean-webpack-plugin');
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
const common = require('./webpack.common.js');
module.exports = merge(common, {
mode: 'production',
plugins: [
// Clean the build folders
new CleanWebpackPlugin(['build'], {
root: process.cwd(), // Otherwise the 'webpack' folder is used
}),
//Make vendor bundle size visible
new BundleAnalyzerPlugin({
analyzerMode: 'static',
openAnalyzer: false,
reportFilename: 'stats/prod-report.html',
}),
],
optimization: {
splitChunks: {
chunks: 'all',
cacheGroups: {
vendor: {
name: 'vendor',
chunks: 'all',
test: /[\/]node_modules[\/]/,
},
},
},
minimizer: [
// Optimize minimization
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
ecma: 6,
mangle: true,
toplevel: true,
},
}),
],
},
});
Надеюсь, это кому-нибудь поможет.