一、介绍
1、webpack官网
2、webpack是一个构建工具(打包器),用于把各种第三方语法比较新的模块构建打包,打包成浏览器能识别的静态资源文件。
在webpack眼中一切皆模块,每个文件都是模块,每个文件都可以通过模块化语法导入/导出。
打包器:从入口文件开始,按照模块依赖进行打包,得到浏览器能够普遍兼容的静态资源文件。
3、架构思维
在某种程度上webpack代表的是一种架构能力(技术选型)。
二、搭建环境
1、准备工具
nodeJS、npm、cnpm、yarn
2、建立目录
react-webpack
3、在目录下执行:npm init
建立一个空的package.json文件
bash
package name: (react-webpack)
version: (1.0.0)
description:
entry point: (index.js) main.js
test command:
git repository:
keywords:
author:
license: (ISC)
About to write to D:\workspace-vscode\react-webpack\package.json:
{
"name": "react-webpack",
"version": "1.0.0",
"main": "main.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"description": ""
}
4、安装webpack
在项目根目录:
bash
cnpm i webpack -g #全局安装
cnpm i webpack -D #再本地安装
安装的是webpack的核心包(提供了很多API、插件)
5、安装webpack-cli
在项目根目录:
bash
cnpm i webpack-cli -g
cnpm i webpack-cli -D
安装的是webpack的命令行工具(它提供了很多命令)
6、安装webpack-dev-server
bash
cnpm i webpack-dev-server -g
cnpm i webpack-dev-server -D
官方推荐的用于构建本地服务器的包
三、编写webpack配置文件
1、webpack是基于nodeJS环境的,怎么让webpack工作?
编写配置文件。官方建议的配置文件:webpack.config.js
2、webpack.config.js最小化配置文件
javascript
//webpack是基于nodeJS的,所以配置文件中的代码都是CommonJS语法
module.exports = {
// 入口
entry: './src/main.js',
// 出口
output: {}
}
3、打包命令:webpack

四、入口出口详解
1、入口的三种写法
相对路径、绝对路径和对象写法
webpack.config.js
javascript
//webpack是基于nodeJS的,所以配置文件中的代码都是CommonJS语法
// 从node进程中引入path模块
const path = require('path')
module.exports = {
// 入口
// entry: './src/main.js', // 相对路径写法
// entry: path.resolve(__dirname, 'src/main.js'), // 绝对路径写法
entry: {
// 可以给入口文件取个名字,给output使用
app: path.resolve(__dirname, 'src/main.js'),
},
// 出口
output: {}
}
2、配置npm scripts
package.json
运行build:
npm run build
yarn build
3、出口配置
webpack.config.js
javascript
//webpack是基于nodeJS的,所以配置文件中的代码都是CommonJS语法
// 从node进程中引入path模块
const path = require('path')
module.exports = {
// 入口
// entry: './src/main.js', // 相对路径写法
// entry: path.resolve(__dirname, 'src/main.js'), // 绝对路径写法
entry: {
// 可以给入口文件取个名字,给output使用
app: path.resolve(__dirname, 'src/main.js'),
},
// 出口
output: {
// 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径
path: path.resolve(__dirname, 'dist'),
// 指定打包结果的JS名称规范
// filename: 'bundle.js' // 量词,一捆、一束
filename: 'js/[name].[chunkhash:8].js'
}
}
4、为什么打包出的文件会叫bundle.js?
bundle是量词,意思是一捆、一束。
表示打包的时候把js代码合并掉了。
5、filename: 'js/[name].[chunkhash:8].js'
说明:
name\]是格式化字符串,用入口key的名称作为name。 \[chunkhash\]这个格式化字符串,用于给输入文件添加hash字符。 \[chunkhash\]有什么特点? 当输入的JS模块所依赖源码发生变化,打包时hash才会发生变化,用于解决浏览器缓存导致的web不更新问题。 生成的文件样例:  五、集成本机服务 1、本地服务配置 webpack.config.js ```javascript //webpack是基于nodeJS的,所以配置文件中的代码都是CommonJS语法 // 从node进程中引入path模块 const path = require('path') module.exports = { // 指定webpack工作模式(只有两种,一种开发模式,另一种是打包模式) mode: 'development', // production // 入口 // entry: './src/main.js', // 相对路径写法 // entry: path.resolve(__dirname, 'src/main.js'), // 绝对路径写法 entry: { // 可以给入口文件取个名字,给output使用 app: path.resolve(__dirname, 'src/main.js'), }, // 出口 output: { // 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径 path: path.resolve(__dirname, 'dist'), // 指定打包结果的JS名称规范 // filename: 'bundle.js' // 量词,一捆、一束 filename: 'js/[name].[chunkhash:8].js' }, // 本地服务配置 devServer: { port: 8000 } } ``` 默认的本地服务器目录是public/index.html 2、配置npm scripts package.json  运行serve: npm run serve yarn serve 六、分离开发环境和生产环境 1、打包的时候devServer只对开发环境有用,所以要拆开不同的环境 2、在根目录建立config目录 config/serve.js config/build.js config/config.js 建立3个配置文件,将webpack.config.js中的配置拆到不同的文件中 serve.js: ```javascript // 只有开发环境才需要用到配置 module.exports = { mode: 'development', // 本地服务配置 devServer: { port: 8000 } } ``` build.js ```javascript // 只有打包时才用到配置 module.exports = { mode: 'production' } ``` config.js ```javascript // 两个环境都需要的公共配置 // 从node进程中引入path模块 const path = require('path') module.exports = { entry: { // 可以给入口文件取个名字,给output使用 app: path.resolve(__dirname, '../', 'src/main.js'), }, // 出口 output: { // 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径 path: path.resolve(__dirname, '../', 'dist'), // 指定打包结果的JS名称规范 // filename: 'bundle.js' // 量词,一捆、一束 filename: 'js/[name].[chunkhash:8].js' }, } ``` 3、使用cross-env模块区分环境 目的是: npm run serve 希望config/serve.js + config/config.js npm run build 希望config/build.js + config/config.js 问题: 在这里如何知道用户执行的是哪个命令? 如何合并配置文件? 安装: ```bash npm i cross-env -D npm i webpack-merge -D ``` 修改package.json  把对象写法改成function的写法: webpack.config.js ```javascript // 引入包 const { merge } = require('webpack-merge') // 合并对象 // 导入模块 const config = require('./config/config') const serve = require('./config/serve') const build = require('./config/build') // 获取全局环境变量(根据package.json里的cross-env配置取值) const NODE_ENV = process.env.NODE_ENV module.exports = function() { console.log('---开始工作 env', NODE_ENV) if (NODE_ENV === 'development') { return merge(config, serve) } else { return merge(config, build) } } ``` 当执行npm run build时,从package.json获取环境为production,返回合并config和build这两个对象 4、因为webpack有两种工作模式,为了让配置更加容易维护,所以我们分离环境 对webpack配置拆分(公共配置、开发环境配置、打包配置),再使用webpack-merge合并配置 七、npm run build时自动删除dist中文件 output增加一个值,clean: true config.js ```javascript // 两个环境都需要的公共配置 // 从node进程中引入path模块 const path = require('path') module.exports = { entry: { // 可以给入口文件取个名字,给output使用 app: path.resolve(__dirname, '../', 'src/main.js'), }, // 出口 output: { // 自定义打包结果的输出目录,默认是dist目录,这里只能使用绝对路径 path: path.resolve(__dirname, '../', 'dist'), // 指定打包结果的JS名称规范 // filename: 'bundle.js' // 量词,一捆、一束 filename: 'js/[name].[chunkhash:8].js', // 每次build打包时,都自动先删除dist中的旧文件 clean: true }, } ```