Webpack 工程实践
多页面配置
js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
entry: {
home: './src/index.js',
other: './src/other.js',
},
output: {
filename: '[name].js', // [name] 代表 home 或 other
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
filename: 'home.html',
chunks: ['home'],
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'other.html',
chunks: ['other'],
}),
],
}const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
mode: 'development',
entry: {
home: './src/index.js',
other: './src/other.js',
},
output: {
filename: '[name].js', // [name] 代表 home 或 other
path: path.resolve(__dirname, 'dist'),
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
filename: 'home.html',
chunks: ['home'],
}),
new HtmlWebpackPlugin({
template: './index.html',
filename: 'other.html',
chunks: ['other'],
}),
],
}Source Map
js
module.exports = {
// 1) 源码映射,生成单独 sourcemap 文件,标识报错列和行
// devtool: 'source-map'
// 2) 不产生单独文件,显示报错的列和行,集成到 JS 中
// devtool: 'eval-source-map'
// 3) 不产生列,生成单独映射文件
// devtool: 'cheap-module-source-map'
// 4) 不产生文件,集成在打包文件中,不产生列
devtool: 'cheap-module-eval-source-map',
}module.exports = {
// 1) 源码映射,生成单独 sourcemap 文件,标识报错列和行
// devtool: 'source-map'
// 2) 不产生单独文件,显示报错的列和行,集成到 JS 中
// devtool: 'eval-source-map'
// 3) 不产生列,生成单独映射文件
// devtool: 'cheap-module-source-map'
// 4) 不产生文件,集成在打包文件中,不产生列
devtool: 'cheap-module-eval-source-map',
}Watch 模式(实时打包)
js
module.exports = {
watch: true,
watchOptions: {
poll: 1000, // 每秒检查 1000 次
aggregateTimeout: 500, // 防抖,500ms 内只打包一次
ignored: /node_modules/,
},
}module.exports = {
watch: true,
watchOptions: {
poll: 1000, // 每秒检查 1000 次
aggregateTimeout: 500, // 防抖,500ms 内只打包一次
ignored: /node_modules/,
},
}常用插件
CleanWebpackPlugin(打包前清理目录)
bash
yarn add clean-webpack-plugin -Dyarn add clean-webpack-plugin -Djs
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
plugins: [new CleanWebpackPlugin()],
}const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
plugins: [new CleanWebpackPlugin()],
}CopyWebpackPlugin(拷贝文件到 dist)
bash
yarn add copy-webpack-plugin -Dyarn add copy-webpack-plugin -Djs
const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
new CopyWebpackPlugin([{ from: './doc', to: './' }]),
],
}const CopyWebpackPlugin = require('copy-webpack-plugin')
module.exports = {
plugins: [
new CopyWebpackPlugin([{ from: './doc', to: './' }]),
],
}BannerPlugin(版权声明,webpack 内置)
在每个 JS 文件开头添加注释:
js
const webpack = require('webpack')
module.exports = {
plugins: [new webpack.BannerPlugin('make hny 2019/12/05')],
}const webpack = require('webpack')
module.exports = {
plugins: [new webpack.BannerPlugin('make hny 2019/12/05')],
}Webpack 跨域问题
devServer 代理
js
module.exports = {
devServer: {
// 方式1:代理到另一个端口
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '/api': '' },
},
},
// 方式2:在 before 钩子中模拟数据
before(app) {
app.get('/user', (req, res) => {
res.json({ name: 'hny' })
})
},
},
}module.exports = {
devServer: {
// 方式1:代理到另一个端口
proxy: {
'/api': {
target: 'http://localhost:3000',
pathRewrite: { '/api': '' },
},
},
// 方式2:在 before 钩子中模拟数据
before(app) {
app.get('/user', (req, res) => {
res.json({ name: 'hny' })
})
},
},
}webpack-dev-middleware(服务端启动 webpack)
前后端开发到一起,请求数据不存在跨域问题:
bash
yarn add webpack-dev-middleware -Dyarn add webpack-dev-middleware -Djs
// server.js
const express = require('express')
const webpack = require('webpack')
const middle = require('webpack-dev-middleware')
const config = require('./webpack.config.js')
const compiler = webpack(config)
const app = express()
app.use(middle(compiler))
app.get('/user', (req, res) => { res.json({ name: 'hny' }) })
app.listen(3000)// server.js
const express = require('express')
const webpack = require('webpack')
const middle = require('webpack-dev-middleware')
const config = require('./webpack.config.js')
const compiler = webpack(config)
const app = express()
app.use(middle(compiler))
app.get('/user', (req, res) => { res.json({ name: 'hny' }) })
app.listen(3000)运行 node server.js 同时启动 webpack 和接口服务。
DefinePlugin(定义环境变量)
webpack 内置插件,可在项目中直接使用:
js
module.exports = {
plugins: [
new webpack.DefinePlugin({
DEV: JSON.stringify('production'),
FLAG: 'true',
}),
],
}
// 项目中使用:
// if (DEV) { url = 'http://localhost:3000' }module.exports = {
plugins: [
new webpack.DefinePlugin({
DEV: JSON.stringify('production'),
FLAG: 'true',
}),
],
}
// 项目中使用:
// if (DEV) { url = 'http://localhost:3000' }WebpackMerge(分环境配置)
bash
yarn add webpack-merge -Dyarn add webpack-merge -Djs
// webpack.base.js - 公共配置
// webpack.prod.js
const { merge } = require('webpack-merge')
const base = require('./webpack.base.js')
module.exports = merge(base, { mode: 'production' })
// webpack.dev.js
module.exports = merge(base, { mode: 'development' })// webpack.base.js - 公共配置
// webpack.prod.js
const { merge } = require('webpack-merge')
const base = require('./webpack.base.js')
module.exports = merge(base, { mode: 'production' })
// webpack.dev.js
module.exports = merge(base, { mode: 'development' })json
"scripts": {
"start": "webpack --config webpack.dev.js"
}"scripts": {
"start": "webpack --config webpack.dev.js"
}Cross-env(运行时环境变量)
bash
npm install cross-envnpm install cross-envjson
"scripts": {
"start": "cross-env NODE_ENV=development webpack"
}"scripts": {
"start": "cross-env NODE_ENV=development webpack"
}js
// 取环境变量
process.env. NODE_ENV// 取环境变量
process.env. NODE_ENVExternals(避免打包第三方库)
当使用 CDN 引入时,可通过 externals 避免重复打包:
js
module.exports = {
externals: {
jquery: '$',
},
}module.exports = {
externals: {
jquery: '$',
},
}
Cao Note