快速上手:
一. 初始化项目(取名字的时候一定不要取工具的名字) npm init -y
二. 安装webpackc
webpack 安装的两种方式:
- 运行
npm install --global webpack
全局安装webpack,这样就能在全局使用webpack命令【不建议】 - 在项目根目录中运行
npm install webpack webpack-cli --save-dev
安准到项目依赖中【建议在本地安装】
三. webpack 基础使用
- 参考 webpack-study 文件夹创建对应的目录,或者看下官网的入门学习。
- 创建 webpack.config.js 文件
const path = require('path');
module.exports = {
entry: './src/index.js', // 入口文件
output: { // 出口
filename: 'bundle.js', // 打包后的文件名
path: path.resolve(__dirname, 'dist') // 打包后的文件路径
}
};
- 在根目录运行
npx webpack
命令,之后就能看到打包好的 bundle.js 文件 - 使用 npm 命令来打包
1. 在 package.json 文件中的 "scripts" 对象中,添加"build": "webpack"
2. 在根目录运行npm run build
命令,等待完成打包
到此为止,我们要看到每次修改后的页面,都必须要先打包,再刷新浏览器,比较繁琐,此时就需要 模块热更新。
webpack-dev-server
- 安装到本地开发依赖:运行
npm i webpack-dev-server -D
- 在 package.json 文件中设置
"scripts": { "dev": "webpack-dev-server" },
- 运行
npm run dev
- 默认会开启 http://localhost:8080/ ,在浏览器中直接访问就行,
- 构建的出口文件默认在
/
根路径,所有要检查 index.html 文件中对打包文件的引用地址是否正确
- <script src="bundle.js"></script>
+ <script src="/bundle.js"></script>
- webpack-dev-server 帮我们打包生成的 bundle.js 文件,并没有存放到实际的物理磁盘上,而是直接托管到了电脑内存中,所以,我们在项目根目录中,根本找不到这个打包好的 bundle.js。我们可以认为:webpack-dev-server 把打包好的文件以一种虚拟的形式,托管到了项目的根目录中,虽然我们看不到它,但是我们可以认为,和 dist、src、node_modules 平级,有一个看不见的文件,叫做 bundle.js
- 注意:这里要考虑兼容问题,2020/11/20
- 建议使用版本
```js
// package.json 文件中
"devDependencies": {
//省略其他配置
"webpack": "^5.6.0",
"webpack-cli": "^3.3.12",
"webpack-dev-server": "^3.11.0"
}
```
- 更多兼容问题,只能百度,或者各种尝试了。
webpack-dev-server 其它设置
- 打包构建成功之后自动在浏览器中打开页面
- 设置 package.json 文件:
"scripts": {"dev": "webpack-dev-server --open"}
- 设置端口号,将默认的 8080 端口改成 3000
- package.json 文件:
"scripts": {"dev": "webpack-dev-server --port 3000"}
- 默认进入首页,而不是根目录
- package.json 文件:
"scripts": {"dev": "webpack-dev-server --contentBase dist"}
- dist 是我的 index.html 所在的文件,当然也可以是 src 等。
- 模块热更新(HMR:hot module replacement)
- package.json 文件:
"scripts": {"dev": "webpack-dev-server --hot"}
- 以上功能连写
webpack-dev-server --open --port 3000 --contentBase dist --hot
- --open、--port 3000、--contentBase dist、--hot,也可以移植到 webpack.config.js 文件中
const webpack = require('webpack'); // 启用热更新 的 第2步
module.exports = {
// ...此处省略
devServer: { // 这是配置 dev-server 命令参数的第二种形式,相对来说,这种方式麻烦一些
open: true, // 打开浏览器
port: 3000, // 设置端口
contentBase: 'dist', // 指定托管的根目录
hot: true // 启用热更新 的 第1步
},
plugins: [ // 配置插件的节点
new webpack.HotModuleReplacementPlugin() // new 一个热更新的模块对象,启用热更新 的 第3步
]
}
此时 package.json 中只需要 "scripts": {"start": "webpack-dev-server"}
注意 这里我写了
"start"
, 启动项目的命令就是npm run start
,而之前用的变量名为"dev"
,响应的就是npm run dev
,当然也可以是其它英文单词,不过习惯性的用"start"
或"dev"
各种 loader(加载器)
webpack,默认只能打包处理 js 类型的文件,无法处理其他非 js 类型的文件。
如果要处理非 js 类型的文件,我们需要安装一些 合适的 第三方加载器(loader)。
安装使用说明
- 安装
npm install xxx-loader
- 打开 webpack.config.js 文件,新增一个配置节点 module,在 module 对象上有个 rules 属性,rules 是个数组,存放了所有第三方文件的匹配和处理规则
- test 属性,用于标识出应该被对应的 loader 进行转换的某个或某些文件。
- use 属性,表示进行转换时,应该使用哪个 loader。
- webpack 处理第三方文件的过程:
1. 发想要处理的文件不是第三方文件,然后去配置文件中,查找有没有对应的第三方 loader 规则
2. 如果能找到对应的规则,就会调用对应的 loader 处理这种文件的规则
3. 在调用 loader 的时候,是从后往前调用的(use: ["style-loader", "css-loader"], 先调用"css-loader",再调用"style-loader")
4. 当最后一个 loader 调用完毕,会把处理结果,直接交给 webpack 进行打包合并,最终输出到 bundle.js 中
举例
- .css文件:
npm install style-loader css-loader -D
module: { // 这个节点,用于配置所有第三方模块 加载器
rules: [ // 所有第三方模块的匹配规则
{
test: /.css$/, use: ["style-loader", "css-loader"] // 配置处理 .css 文件的第三方 loader 规则
}
]
}
- .less 文件:
npm install less less-loader -D
module: {
rules: [
{
test: /.less$/, use: ["style-loader", "css-loader", "less-loader"]
}
]
}
- .sass 文件:
npm install node-sass sass-loader -D
module: {
rules: [
{
test: /.scss$/, use: ["style-loader", "css-loader", "sass-loader"]
}
]
}
- .ts 文件:
npm install --save-dev ts-loader
没验证过
module: {
rules: [
{
test: /.ts$/, use: 'ts-loader'
}
]
}
- .jsx 文件:
npm install --save-dev babel-core babel-preset-es2015 babel-loader jsx-loader
没验证过
module: {
rules: [
{test: /.js$/, loader: "babel", exclude: /node_modules/},
{test: /.jsx$/, loader: "jsx-loader"}
]
}
-
在react中启用jsx语法 (参考 下文 Babel )
- 运行
npm install babel-core babel-loader babel-plugin-transform-runtime -D
- 运行
npm install abel-preset-env babel-preset-stage-0 -D
- 能够识别转换 jsx 语法的包:
npm install babel-preset-react -D
- 添加
.babelrc
配置文件{ "presets": ["env", "stage-0", "react"], "plugins": ["transform-runtime"] }
- 运行
-
图片 文件:
npm install url-loader file-loader -D
module: {
rules: [
// test: /.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader'
test: /.(jpg|png|gif|bmp|jpeg)$/, use: 'url-loader?limit=240&name=[hash:8]-[name].[ext]'
]
}
-
打包后默认会改变图片的名字,并转成 base64 字符串
-
如何有选择的转成 base64 :
limit 给点的值是图片的大小,单位是 byte,
当引用的图片大小 大于或等于 给定的值,则不会被转换位base64格式的字符串,
如果 小于 给点的值,则会被转成base64格式的字符串
作用是让小图片转成 base64 ,而大图片则不需要 -
如何不改变名字:
name=[hash:8]-[name].[ext]
[name]代表图片之前叫什么名字,打包过后依旧叫什么
[ext] 代表图片之前是什么尾缀,打包过后依旧是什么
[hash:8]- 每一张图片前面增加一段hash值,防止重命名,hash值是32位的,:8
代表截取前8位,不能超过32位
-
-
字体文件
module: {
rules: [
test: /.(ttf|eot|svg|woff|woff2)$/, use: 'url-loader'
]
}
Babel javaScript 语法编译器
在 webpack 中,默认只能处理一部分 ES6 的新语法,一些更高级的ES6语法或者 ES7语法,webpack 是处理不了的。
这时候,就需要借助于第三方的 loader,来帮助 webpack 处理这些高级的语法,当第三方 loader 把高级语法转换为低级的语法,
会把结果交给 webpack 去打包到 bundle.js 中。
通过 Babel,可以帮助我们将高级的语法转换为低级的语法
- 在 webpack 中,可以运行如下两套命令,安装两套包,去暗转 Babel 相关的 loader 功能
1.1 第一套包:npm i babel-core babel-loader babel-plugin-transform-runtime -D
1.2 第二套包:npm i babel-core babel-preset-env babel-preset-stage-0 -D
- 打开 webpack 的配置文件,在 module 节点下的 rules 数组中,添加一个新的匹配规则
2.1 {test:/.js$/, use: 'babel-loader', exclude: /node_modules/}
2.2 在配置 babel-loader 规则的时候,必须把 node_modules 目录,通过 exclude 选项排除掉,原因有俩:
2.2.1 如果不排除 node_modules,则 Babel 会把 node_modules 中所有的第三方 Js 文件,都打包编译,这样会非常消耗 CPU,同时打包速度非常慢
2.2.2 哪怕,最终 Babel 把所有 node_modules 中的Js转换完毕了,但是项目也无法正常运行! - 在项目的根目录中,新建一个叫做 .babelrc 的 Babel 配置文件,这个配置文件,属于JSON格式,所以在写 .babelrc 配置的时候,
必须符合JSON语法规范(不能写注释,字符串必须用双引号
3.1 在 .babelrc 写如下的配置:
"presets" 可以理解成:语法
"plugins" 插件,这里指 babel 的插件{ "presets": ["env", "stage-0"], "plugins": ["transform-runtime"] }
- 了解:目前,我们安装的 babel-preset-env,是比较新的ES语法,之前,我们安装的是 babel-preset-es2015 (ES6),现在,出了
一个更新的语法插件,叫做 babel-preset-env,它包含了所有的 和 ES***相关的语法