获取全套webpack 4.x教程,请访问瓦力博客
我们正常开发项目会有两种模式,一种是开发模式,另一种是生产模式。在开发模式中,为了便于代码调试方便我们快速定位错误,不会压缩混淆源代码。但在生成模式中,就不需要调试代码,而是需要更快的页面加载,缓存优化等来提高用户体验。因此开发环境和生产环境需要单独配置。
1.开发和生产区别
\ | 开发模式 | 生产模式 |
---|---|---|
css | 处理css文件 添加厂商前缀 提取css |
处理css文件 添加厂商前缀 提取css文件 压缩css 去除注释 |
less | 处理less文件 添加厂商前缀 提取css |
处理less文件 添加厂商前缀 提取css 压缩css 去除注释 |
sass | 处理sass文件 添加厂商前缀 提取css |
处理sass文件 添加厂商前缀 提取css 压缩css 去除注释 |
图片 | 去缓存 压缩 |
去缓存 压缩 |
字体 | 去缓存 | 去缓存 |
html | 去空格 | 去空格 压缩 去注释 |
js | es6转es5 懒加载 js语法检测 |
去注释 压缩 混淆 e6转e5 懒加载 js语法检测 |
devServer | 需要 | 不需要 |
清除dist | 清除dist目录 | 清除dist目录 |
2.文件结构
webpack官方建议开发模式和生产模式的配置分开,然后将两者的公共配置提取出来。这种方法好处就是直接用文件区分环境,如webpack.dev.js
就是开发环境,webpack.prod.js
就是生产环境。小菜决定不使用官方推荐的模式,而是采用自己习惯的配置模式。
myProject
+|-build
+ |-base
+ |-path.js
+ |-config.js
+ |-mode.js
+ |-entry.js
+ |-devtool.js
+ |-module.js
+ |-plugins.js
+ |-devServer.js
+ |-optimization.js
+ |-output.js
|-dist
|-node_modules
|-src
|-util
|-math.js
|-assets
|-css
|-index.css
|-less
|-index.less
|-sass
|-index.scss
|-images
|-wali_logo.png
|-index.html
|-index.js
|-package.json
|-webpack.config.js
|-postcss.config.js
|-.babelrc
3.模块化
在模块化之前,小菜先更新clean-webpack-plugin
插件,最新版本时3.0.0
,更新完成后去package.json看下版本是不是最新的。
yarn add clean-webpack-plugin
更新完成后,请按官方文档说明修改之前webpack.config.js
的写法
+ const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //清除
+ new CleanWebpackPlugin()
4.package.json
{
"name": "webpack",
"version": "1.0.0",
"description": "webpack测试",
"sideEffects":[
"*.css"
],
"main": "index.js",
"author": "wali",
"private": true,
"license": "MIT",
"scripts": {
"dev": "npx webpack-dev-server --colors --mode=development",
"prod": "npx webpack --colors --mode=production",
"build": "npx webpack --colors --mode=development",
"analyse": "npx webpack --profile --json> stats.json --colors --mode=development"
},
"dependencies": {
"@babel/core": "^7.4.5",
"@babel/plugin-syntax-dynamic-import": "^7.2.0",
"@babel/plugin-transform-runtime": "^7.4.4",
"@babel/polyfill": "^7.4.4",
"@babel/preset-env": "^7.4.5",
"@babel/runtime": "^7.4.5",
"@babel/runtime-corejs2": "^7.4.5",
"autoprefixer": "^9.5.1",
"babel-loader": "^8.0.6",
"clean-webpack-plugin": "^3.0.0",
"css-loader": "^2.1.1",
"extract-text-webpack-plugin": "^3.0.2",
"file-loader": "^3.0.1",
"html-loader": "^0.5.5",
"html-webpack-plugin": "^3.2.0",
"image-webpack-loader": "^4.6.0",
"json5-loader": "^2.0.0",
"less": "^3.9.0",
"less-loader": "^5.0.0",
"loadsh": "^0.0.4",
"lodash": "^4.17.11",
"node-sass": "^4.12.0",
"postcss-loader": "^3.0.0",
"sass-loader": "^7.1.0",
"style-loader": "^0.23.1",
"webpack": "^4.32.0",
"webpack-cli": "^3.3.2",
"webpack-dev-server": "^3.4.1"
},
"devDependencies": {
"webpack-bundle-analyzer": "^3.3.2"
}
}
5.path.js
路径build/base/path.js
const path = require('path');
let dirPath = {};
dirPath.rootDir = path.resolve(__dirname, '../../'); //根路径
dirPath.nodeModule = path.resolve(dirPath.rootDir, './node_modules'); //包路径
dirPath.src = path.resolve(dirPath.rootDir,'./src'); //源文件
dirPath.dist = path.resolve(dirPath.rootDir,'./dist'); //生成线上
dirPath.assets = 'assets'; //静态资源
dirPath.css = 'assets/css'; //css
dirPath.sass = 'assets/sass' //sass
dirPath.less = 'assets/less'; //less
dirPath.images = 'assets/images'; //images
dirPath.iconfont = 'assets/iconfont'; //iconfont
//将srcPath 挂载出去
module.exports = dirPath;
6.config.js
路径build/base/config.js
读取cli
中参数--mode=development
来判断当前是开发环境还是生产环境,config
一些基础配置
/****
*** config配置
****/
let _mode = process.argv[process.argv.length - 1];
let env = _mode.replace(/--mode=(.+)/g,"$1");
let config = {
NODE_ENV: env == 'development'?'development':'production', //development 开发 production 线上
publicPath: env == 'development'?'/':'http://www.waliblog.com',
apiUrl:'http://www.waliblog.com',
port: 9999
}
module.exports = config;
7.mode.js
路径build/mode.js
设置webpack是生成模式还是开发模式
const config = require('./base/config');
let mode = config.NODE_ENV == 'development'?'development':'production';
module.exports = mode;
8.devServer.js
路径build/devServer.js
const dirPath = require('./base/path');
const config = require('./base/config');
let devServer = {
contentBase: dirPath.dist,
clientLogLevel: 'info',
open:true, //启动时默认打开浏览器
host:'localhost', //域名 0.0.0.0局域网可访问
port:config.port || '9999',
inline:true, //实时更新
hot:true, //热替换
hotOnly:false, //true禁止浏览器自动刷新,false浏览器刷新
proxy:{
'/':{
target: config.apiUrl
},
'/upload':{
target: config.apiUrl
}
}
}
module.exports = devServer
9.entry.js
路径build/entry.js
const dirPath = require('./base/path');
let entry = {
main: dirPath.src + '/index.js'
}
module.exports = entry;
10.devtool.js
路径build/devtool.js
const config = require('./base/config');
const devtool = config.NODE_ENV === 'development'?'cheap-eval-source-map':'cheap-source-map';
module.exports = devtool;
11.module.js
路径build/module.js
const dirPath = require('./base/path');
const config = require('./base/config');
let _module = {
rules:[
{
test:/\.css$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:1
}
},
'postcss-loader'
]
},
{
test:/\.scss$/,
use:[
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'sass-loader',
'postcss-loader'
]
},
{
test: /\.less$/,
use: [
'style-loader',
{
loader:'css-loader',
options:{
importLoaders:2
}
},
'less-loader',
'postcss-loader'
]
},
{
test:/\.(png|svg|jpeg|jpg|gif)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name][sha512:hash:base64:7].[ext]', //[path] 上下文环境路径
outputPath: dirPath.images, //输出路径
publicPath: config.NODE_ENV === 'development'?dirPath.images:dirPath.images //公共路径
}
},
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true, // webpack@1.x
disable: true, // webpack@2.x and newer
},
},
]
},
{
test: /\.html$/,
use:[
{
loader:'html-loader',
options:{
arrts:['img:src','img:data-src'],
minimize: config.NODE_ENV === 'development'? false:true //是否压缩html
}
}
]
},
{
test: /(iconfont.svg)|\.(woff|woff2|eot|ttf|otf)$/,
use:[
{
loader:'file-loader',
options:{
name:'[name].[ext]', //[path] 上下文环境路径
outputPath: dirPath.iconfont, //输出路径
publicPath: config.NODE_ENV === 'development'? dirPath.iconfont: dirPath.iconfont, //公共路径
}
}
]
},
{
test: /\.js$/,
exclude: /(node_modules|bower_components|lib)/,
loader: 'babel-loader'
}
]
}
module.exports = _module;
12.pligins.js
路径build/pligins.js
const dirpath = require('./base/path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin'); //生成html文件
const { CleanWebpackPlugin } = require('clean-webpack-plugin'); //清除
let plugins = [
new HtmlWebpackPlugin({
title: '瓦力博客',
template: dirpath.src + '/index.html' //以src/index.html为编译模板
}),
new CleanWebpackPlugin(),
new webpack.HotModuleReplacementPlugin()
]
module.exports = plugins;
13.optimization.js
路径build/optimization.js
let optimization = {
usedExports: true,
splitChunks: {
chunks: 'all',
minSize: 30000,
maxSize: 0,
minChunks: 1,
maxAsyncRequests: 5,
maxInitialRequests: 3,
automaticNameDelimiter: '~',
name: true,
cacheGroups: {
vendors: {
test: /[\\/]node_modules[\\/]/,
priority: -10
},
default: {
minChunks: 2,
priority: -20,
reuseExistingChunk: true
}
}
}
}
module.exports = optimization
14.output.js
路径build/output.js
const srcPath = require('./base/path');
const config = require('./base/config');
let output = {
path: srcPath.dist,
filename: '[name].[hash].js',
publicPath: config.publicPath
}
module.exports = output;
15.webpack.config.js
const _mode = require('./build/mode');
const _devtool = require('./build/devtool');
const _entry = require('./build/entry');
const _module = require('./build/module');
const _plugins = require('./build/plugins');
const _devServer = require('./build/devServer');
const _optimization = require('./build/optimization');
const _output = require('./build/output');
module.exports = {
mode: _mode,
devtool: _devtool,
entry: _entry,
module: _module,
plugins: _plugins,
devServer: _devServer,
optimization: _optimization,
output: _output
}
将webpack配置拆分成单个js文件,然后在组装在一起,通过cli参数来区分是开发模式还是生产模式。拆分好后,在package.json
文件中找到scripts
运行对应的命令,如果能够运行成功,说明我们目前拆分的没有问题。如果报错了,请认真检查报错原因。
共同学习,写下你的评论
评论加载中...
作者其他优质文章