webpack4之development和production打包配置


package.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
# npm i -D webpack-merge

{
"name": "webpack-demo",
"sideEffects": ["*.css", "./src/**/*.js", "./src/**/*.ts"], // 有时候项目中直接是import './index.js',不能忽略这些
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"bundle": "webpack --watch",
"watch": "webpack-dev-server",
"middleware": "node server.js",
"dev": "webpack-dev-server --config ./build/webpack.dev.js",
"build": "webpack --config ./build/webpack.prod.js"
}
}
webpack.common.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// ./build/webpack.common.js
const webpack = require('webpack')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const {CleanWebpackPlugin} = require('clean-webpack-plugin')
const path = require('path')

module.exports = {
entry: {
main: './src/index.js'
},
resolve: {
extensions: ['.js', '.jsx'], // 可以隐式的引用文件:import a form '../src/A'
alias: {
A: path.resolve(__dirname, '../src/A') // 可以省略引用:import a from 'Ethan/A'
}
},
module: {
rules: [{
test: /\.js$/,
exclude: /node_modules/,
loader: 'babel-loader'
}, {
test: /\.(jpg|png|gif|mp4|mp3)$/,
use: {
loader: 'url-loader',
options: {
name: '[name]_[hash:7].[ext]',
outputPath: 'images/',
limit: 10240
}
}
}, {
test: /\.(eot|ttf|svg)$/,
use: {
loader: 'file-loader',
}
}, {
test: /\.html$/,
use: {
loader: 'html-loader',
options: {
// 默认只识别img:src,所以不配置的时候img:src会用url-loader打包,其他就忽略
attrs: ['img:src', 'img:data-src', 'audio:src', 'video:src' ],
minimize: false,
removeComments: true,
collapseWhitespace: false
}
}]
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'
}),
new CleanWebpackPlugin(['dist'])
]
}
development配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
// ./build/webpack.dev.js

const webpack = require('webpack')
const commonConfig = require('./webpack.common.js')
const merge = require('webpack-merge')
const path = require('path')
const IP = require('ip').address()

const devConfig = {
mode: 'development',
devtool: 'cheap-module-eval-source-map',
devServer: {
contentBase: './dist',
open: true,
port: 8080,
host: IP,
hot: true
},
module: {
rules: [{
test: /\.scss$/,
use: [
'style-loader',
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'postcss-loader',
'sass-loader'
]
}, {
test: /\.css$/,
use: [
'style-loader', 'css-loader', 'postcss-loader'
]
}]
},
plugins: [
new webpack.HotModuleReplacementPlugin(),
// 可以将webpack设置的变量在js中使用,js中就有了_DEV_的变量
new webpack.DefinePlugin({
_DEV_: JSON.stringify(['./index.js', './index1.js'])
})
],
optimization: {
usedExports: true
},
output: {
filename: '[name].js',
chunkFilename: '[name].chunk.js',
path: path.resolve(__dirname, 'dist')
}
}

module.exports = merge(commonConfig, devConfig)
production配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
// ./build/webpack.prod.js

const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const TerserJSPlugin = require('terser-webpack-plugin')
const OptimizeCSSAssetsPlugin = require('optimize-css-assets-webpack-plugin')
const commonConfig = require('./webpack.common.js')
const merge = require('webpack-merge')
const path = require('path')

const prodConfig = {
mode: 'production',
devtool: 'cheap-module-eval-source-map',
plugins: [
new MiniCssExtractPlugin({
filename: '[name].[contenthash].css',
chunkFilename: '[id].[contenthash].css'
})
],
optimization: {
minimizer: [new TerserJSPlugin({}), new OptimizeCSSAssetsPlugin({})],
},
module: {
rules: [{
test: /\.scss$/,
use: [
MiniCssExtractPlugin.loader,
{
loader: 'css-loader',
options: {
importLoaders: 2
}
},
'postcss-loader',
'sass-loader'
]
}, {
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'
]
}]
},
output: {
filename: '[name].[contenthash].js',
chunkFilename: '[name].[contenthash].chunk.js',
path: path.resolve(__dirname, 'dist')
}
}

module.exports = merge(commonConfig, prodConfig)
.babelrc
1
2
3
4
5
6
7
8
9
10
11
{
"presets": [["@babel/preset-env", {
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage"
}]]
}
获取指定目录下的指定类型文件路径传给js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
// ./build/getListenFiles.js
const pathJoin = require('path').join
var fs = require('fs')
function getListenFiles (startPath, parentPath, typeFile) {
const result = []
function finder (path, parPath) {
const files = fs.readdirSync(path) // 同步
files.forEach(val => {
const fPath = pathJoin(path, val)
const stats = fs.statSync(fPath) // 同步
if (stats.isDirectory()) finder(fPath, `${parPath}/${val}`)
const reg = RegExp(`\\.${typeFile}$`)
if (stats.isFile() && reg.test(val)) result.push(`${parPath}/${val}`)
})
}
finder(startPath, parentPath)
return result
}
module.exports = getListenFiles

// ./build/webpack.dev.js
const webpack = require('webpack')
const setListenFiles = require('./setListenFiles')
var filePath = path.resolve(__dirname, '../src/page') // 遍历哪个目录
const fileList = setListenFiles(filePath, './page', 'js') // 添加前缀和筛选js还是ts
console.log(fileList)

module.exports = {
// 将fileList传给js使用
new webpack.DefinePlugin({ fileList: JSON.stringify(fileList) })]
}
多页面配置
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
// ./build/webpack.common.js
module.exports = {
entry: {
one: './src/index1.js',
two: './src/index2.js'
},
plugins: [
new HtmlWebpackPlugin({
template: './src/index1.html',
filename: 'index1.html', // 生成的html文件名
chunks: ['one'] // 入口文件名
}),
new HtmlWebpackPlugin({
template: './src/index2.html',
filename: 'index2.html',
chunks: ['two']
}),
new CleanWebpackPlugin(['dist'])
]
}