我正在尝试使用webpack减少我的生产包。现在我有这个输出
Webpack compilation completed
Hash: c3bd2a36378a1a1de0e5
Version: webpack 2.3.3
Time: 34359ms
Asset Size Chunks Chunk Names
b56ef938f034f4024bf903e4a84661ed.png 14.9 kB [emitted]
app.4d4b60bfa2635b5338de.js 403 kB 0 [emitted] [big] app
vendor.8415656eaa2192fe6d27.js 976 kB 1 [emitted] [big] vendor
app.3751d8e65855ec1a82d774639233c975.css 209 kB 0 [emitted] app
vendor.659d5b29c7a69fcec90ce077c2814915.css 2.15 kB 1 [emitted] vendor
index.html 682 bytes [emitted]
Child html-webpack-plugin for "index.html":
Asset Size Chunks Chunk Names
index.html 545 kB 0
我尝试使用webpack-bundle-analyser
分析我的捆绑包,然后我
我可以做些什么来减少我使用的库的大小吗?在我的代码中我正在使用
import xxx from 'module/lib/xxx'
而不是
import { xxx } from 'module'
我尝试了很多东西,但我无法继续下去,所以如果你有更多的想法,我很乐意尝试。
以下是我的配置
webpack.config.js
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin
const path = require('path')
const webpack = require('webpack')
const ExtractTextPlugin = require('extract-text-webpack-plugin')
const LodashModuleReplacementPlugin = require('lodash-webpack-plugin')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const project = require('./project.config')
const __DEV__ = project.globals.__DEV__
const __PROD__ = project.globals.__PROD__
const __TEST__ = project.globals.__TEST__
const APP_ENTRIES = [project.paths.client('index.js')]
if (__DEV__) {
APP_ENTRIES.unshift(
'react-hot-loader/patch',
`webpack-dev-server/client?http://${project.server_host}:${project.server_port}`,
'webpack/hot/only-dev-server'
)
}
const config = {
devtool: project.compiler_devtool,
externals: {
leaflet: 'L',
},
entry: {
app: APP_ENTRIES,
vendor: project.compiler_vendors,
},
output: {
filename: `[name].[${project.compiler_hash_type}].js`,
path: project.paths.dist(),
publicPath: project.compiler_public_path,
},
resolve: {
mainFields: ['module', 'browser', 'main'],
modules: [
project.paths.client(),
'node_modules',
],
alias: {
config: path.resolve(project.paths.client(), 'config', project.flavor),
},
},
module: {
rules: [{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
}, {
test: /\.css$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
options: {
minimize: true,
},
}],
}, {
test: /\.scss$/,
use: [{
loader: 'style-loader',
}, {
loader: 'css-loader',
options: {
localIdentName: '[name]__[local]___[hash:base64:5]',
modules: true,
importLoaders: 1,
minimize: true,
},
}, {
loader: 'postcss-loader',
options: {
plugins: () => [
require('autoprefixer'),
],
},
}, {
loader: 'sass-loader',
options: {
includePaths: [].concat(project.paths.client('styles')),
data: '@import "base.scss";',
},
}],
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader',
options: {
limit: 8192,
},
}],
},
plugins: [
new BundleAnalyzerPlugin(),
new LodashModuleReplacementPlugin({
currying: true,
flattening: true,
paths: true,
placeholders: true,
shorthands: true,
}),
new webpack.DefinePlugin(project.globals),
new webpack.optimize.OccurrenceOrderPlugin(),
],
node: {
fs: 'empty',
net: 'empty',
tls: 'empty',
},
}
if (__DEV__) {
config.plugins.push(
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
new HtmlWebpackPlugin({
template: project.paths.public('index.html'),
hash: false,
filename: 'index.html',
inject: 'body',
})
)
} else if (__PROD__) {
config.plugins.push(
new webpack.LoaderOptionsPlugin({
minimize: true,
debug: false,
}),
new HtmlWebpackPlugin({
inject: true,
template: project.paths.public('index.html'),
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true,
},
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // React doesn't support IE8
warnings: false,
},
mangle: {
screw_ie8: true,
},
output: {
comments: false,
screw_ie8: true,
},
}),
new webpack.optimize.AggressiveMergingPlugin())
}
if (!__TEST__) {
config.plugins.push(
new webpack.optimize.CommonsChunkPlugin({
name: 'vendor',
})
)
}
if (__TEST__) {
config.module.rules.push({
test: /\.spec\.js?$/,
loader: 'babel-jest',
exclude: /node_modules/,
})
}
if (!__DEV__) {
config.module.rules
.filter(rule => String(rule.test).includes('css'))
.forEach((rule) => {
const first = rule.use[0]
const rest = rule.use.slice(1)
rule.use = ExtractTextPlugin.extract({
fallback: first,
use: rest,
})
})
config.plugins.push(
new ExtractTextPlugin({
filename: '[name].[contenthash].css',
allChunks: true,
}))
}
module.exports = config
project.config.js
const path = require('path')
const pck = require('../package.json')
const environments = require('./env.config')
const config = {
env: process.env.NODE_ENV || 'development',
flavor: process.env.NODE_FLAVOR || 'local',
path_base: path.resolve(__dirname, '..'),
dir_client: 'src',
dir_dist: 'dist',
dir_public: 'public',
server_host: 'localhost',
server_port: process.env.PORT || 3000,
compiler_devtool: 'eval',
compiler_public_path: '/',
compiler_hash_type: 'hash',
compiler_fail_on_warning: false,
compiler_stats: {
chunks: false,
chunkModules: false,
colors: true,
},
compiler_vendors: Object.keys(pck.dependencies).filter(module => !['antd'].some(forbidden => forbidden === module)),
}
function base(...args) {
return path.resolve(...[config.path_base].concat(args))
}
config.paths = {
base,
client: base.bind(null, config.dir_client),
dist: base.bind(null, config.dir_dist),
public: base.bind(null, config.dir_public),
}
config.globals = {
'process.env': {
NODE_ENV: JSON.stringify(config.env),
},
NODE_ENV: config.env,
__DEV__: config.env === 'development',
__PROD__: config.env === 'production',
__TEST__: config.env === 'test',
}
const overrides = environments[config.env]
if (overrides) {
Object.assign(config, overrides(config))
}
module.exports = config
env.config.js
module.exports = {
development: config => ({
compiler_public_path: `http://${config.server_host}:${config.server_port}/`,
}),
production: () => ({
compiler_public_path: '/',
compiler_devtool: false,
compiler_hash_type: 'chunkhash',
compiler_stats: {
chunks: false,
chunkModules: false,
colors: true,
},
}),
}
.babelrc
{
"presets": [
["es2015", {"modules": false}],
"react"
],
"plugins": [
"lodash",
["transform-runtime", {
"polyfill": false,
"regenerator": true
}],
["import", { "libraryName": "antd", "style": "css" }],
["transform-imports", {
"lodash": {
"transform": "lodash/${member}",
"preventFullImport": true
},
"lodash-es": {
"transform": "lodash/${member}",
"preventFullImport": true
}
}]
],
"env": {
"test": {
"plugins": [
"system-import-transformer",
"transform-es2015-modules-commonjs"
]
}
}
}
答案 0 :(得分:2)
我有webpack 6.0.1。根据我测试过的cron-job.org,可以为webpack.config.js使用以下配置建议:
//webpack.config.js
module.exports = {
...
devtool: 'cheap-module-source-map',
...
plugins : [
...
new webpack.DefinePlugin({ 'process.env.NODE_ENV': JSON.stringify('production') }),
new webpack.optimize.ModuleConcatenationPlugin(),
new webpack.HashedModuleIdsPlugin({
hashFunction: 'sha256',
hashDigest: 'hex',
hashDigestLength: 4
}),
new webpack.optimize.OccurrenceOrderPlugin(),
new webpack.NoEmitOnErrorsPlugin(),
],
...
optimization: {
namedModules: false,
namedChunks: false,
nodeEnv: 'production',
flagIncludedChunks: true,
occurrenceOrder: true,
sideEffects: true,
usedExports: true,
concatenateModules: true,
splitChunks: {
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: 'vendor',
chunks: 'all'
}
},
minSize: 30000,
maxAsyncRequests: 5,
maxAsyncRequests: 3,
},
noEmitOnErrors: true,
minimize: true,
minimizer: [
// we specify a custom UglifyJsPlugin here to get source maps in production
new UglifyJsPlugin({
cache: true,
parallel: true,
uglifyOptions: {
compress: false,
ecma: 6,
mangle: true
},
sourceMap: true
})
],
removeAvailableModules: true,
removeEmptyChunks: true,
mergeDuplicateChunks: true,
},
...
}
评论: