一、介绍
1、webpack官网
https://webpack.js.org/
2、webpack是一个构建工具(打包器),用于把各种第三方语法比较新的模块构建打包,打包成浏览器能识别的静态资源文件。
在webpack眼中一切皆模块,每个文件都是模块,每个文件都可以通过模块化语法导入/导出。
打包器:从入口文件开始,按照模块依赖进行打包,得到浏览器能够普遍兼容的静态资源文件。
3、架构思维
在某种程度上webpack代表的是一种架构能力(技术选型)。
二、搭建环境
1、准备工具
nodeJS、npm、cnpm、yarn
2、建立目录
react-webpack
3、在目录下执行:npm init
建立一个空的package.json文件
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
在项目根目录:
cnpm i webpack -g #全局安装
cnpm i webpack -D #再本地安装
安装的是webpack的核心包(提供了很多API、插件)
5、安装webpack-cli
在项目根目录:
cnpm i webpack-cli -g
cnpm i webpack-cli -D
安装的是webpack的命令行工具(它提供了很多命令)
6、安装webpack-dev-server
cnpm i webpack-dev-server -g
cnpm i webpack-dev-server -D
官方推荐的用于构建本地服务器的包
三、编写webpack配置文件
1、webpack是基于nodeJS环境的,怎么让webpack工作?
编写配置文件。官方建议的配置文件:webpack.config.js
2、webpack.config.js最小化配置文件
//webpack是基于nodeJS的,所以配置文件中的代码都是CommonJS语法
module.exports = {
// 入口
entry: './src/main.js',
// 出口
output: {}
}
3、打包命令:webpack
四、入口出口详解
1、入口的三种写法
相对路径、绝对路径和对象写法
webpack.config.js
//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
//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
//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:
// 只有开发环境才需要用到配置
module.exports = {
mode: 'development',
// 本地服务配置
devServer: {
port: 8000
}
}
build.js
// 只有打包时才用到配置
module.exports = {
mode: 'production'
}
config.js
// 两个环境都需要的公共配置
// 从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
问题:
在这里如何知道用户执行的是哪个命令?
如何合并配置文件?
安装:
npm i cross-env -D
npm i webpack-merge -D
修改package.json
把对象写法改成function的写法:
webpack.config.js
// 引入包
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
// 两个环境都需要的公共配置
// 从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
},
}