为了账号安全,请及时绑定邮箱和手机立即绑定

webpack 模块化区分开发和生产(14)

标签:
webpack

获取全套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运行对应的命令,如果能够运行成功,说明我们目前拆分的没有问题。如果报错了,请认真检查报错原因。

点击查看更多内容
TA 点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
  • 推荐
  • 评论
  • 收藏
  • 共同学习,写下你的评论
感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消