Webpack
静态模块化打包工具
打包流程
- 根据命令或配置文件找到入口文件
- 从入口开始,生成一个依赖关系图,此依赖关系图包含程序所需的所有模块
- 根据依赖关系图,遍历图结构,打包一个个模块
安装Webpack
- 创建package.json文件,用于管理项目信息、库依赖
- 安装局部webpack
- 使用webpack
1 2 3 4
| npm init npm install webpack -D npm install webpack-cli -D #webpack4.0+执行时需要依赖到webpack-cli npx webpack #npx会去当前根目录的node_module里找webpack,不会去全局找
|
- 可以在package.json文件中,添加脚本()
1 2 3 4
| "scripts": { "build": "webpack", } # 之后运行npm run build就可执行脚本打包,且webpack使用的使局部
|
- 根目录
webpack.config.js
文件进行配置
1 2 3 4 5 6 7 8
| const path = require('path'); module.exports = { entry: "./src/index.js", output: { filename: "bundle.js", path: path.resolve(__dirname, "./dist") }, }
|
loader 的简单使用
loader 让 webpack 能够去处理那些非 JavaScript 文件(webpack 自身只理解 JavaScript)。loader 可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后你就可以利用 webpack 的打包能力,对它们进行处理。
样式
根目录下新建文件
1 2 3 4 5 6
| import "../css/style.css"
const divEl = document.createElement('div'); divEl.className = "title"; divEl.innerHTML = "hello";
|
1 2 3 4
| .title { background-color: skyblue; }
|
执行npm run build
会直接报错,因为缺少解析style.css的loader
所以需要安装css-loader
1
| npm install css-loader -D
|
在webpack.config.js
配置css-loader
1 2 3 4 5 6 7 8 9 10 11
| module: { rules: [ { test: /\.css$/, use: [ "css-loader" ] }, ] }
|
再次运行npm run build
没报错,但css没生效,因为css-loader只会进行解析,不会将解析后的css插入页面中
需要安装style-loader
1
| npm install style-loader -D
|
同样在webpack.config.js
配置style-loader
1 2 3 4 5 6 7 8 9 10 11 12
| module: { rules: [ { test: /\.css$/, use: [ "style-loader" "css-loader" ] }, ] }
|
运行npm run build
页面会成功展示css
同样道理可以配置解析less
,scss
安装less-loader
,并进行配置可以就less文件转换为css
1
| npm install less-loader -D
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, type: "asset" }, ] }
|
图片
安装file-loader
1 2 3 4 5 6 7 8 9 10 11
| module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, use: { loader: "file-loader", } }, ] }
|
打包后的文件名会是乱码,如果要保留名字,同时防止命名冲突,可以进行配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| module: { rules: [ { test: /\.(png|jpe?g|gif|svg)$/i, use: { loader: "file-loader", options: { outputPath: "img", name: "[name]_[hash:8].[ext]" } } }, ] }
|
- [ext]: 处理文件的扩展名
- [name]:处理文件的名称
- [hash]:文件的内容,使用MD4的散列函数处理,生成的一个128位的hash值(32个十六进制)
- [hash:]:截图hash的长度
Plugin 的简单使用
loader 被用于转换某些类型的模块,而插件则可以用于执行范围更广的任务。插件的范围包括,从打包优化和压缩,一直到重新定义环境中的变量。插件接口功能极其强大,可以用来处理各种各样的任务。
CleanWebpackPlugin
打包后,自动删除旧的包
- 安装插件
1
| npm install clean-webpack-plugi -D
|
- 配置插件
1 2 3 4 5 6
| const { CleanWebpackPlugin } = require("clean-webpack-plugin") module.exports = { plugins: [ new CleanWebpackPlugin() ] }
|
HtmlWebpackPlugin
因为打包后是没有index.html文件,而进行项目部署必须要对应入口文件index.html
,所以也要对index.heml
进行打包
- 安装插件
1
| npm install html-webpack-plugin -D
|
- 配置插件
1 2 3 4 5 6 7 8 9
| const HtmlWebpackPlugin = require("html-webpack-plugin"); module.exports = { plugins: [ new HtmlWebpackPlugin({ title: "webpack案例", template: "./src/public/index.html" }), ] }
|
DefinePlugin
此插件是webpack内置的,用于允许在编译时创建配置的全局常量
1 2 3 4 5 6 7 8 9 10
| const { DefinePlugin } = require('webpack'); module.exports = { plugins: [ new DefinePlugin({ BASE_URL: '"./"', __VUE_OPTIONS_API__: true, __VUE_PROD_DEVTOOLS__: false }) ] }
|
CopyWebpackPlugin
可以将需要的文件,复制到dist文件夹中
- 安装
1
| npm install copy-webpack-plugin -D
|
- 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| const CopyWebpackPlugin = require("copy-webpack-plugin") module.exports = { plugins: [ new CopyWebpackPlugin({ patterns: [ { from: "./src/public", globOptions: { ignore: [ '**/index.html' ] } } ] }), ] }
|
Babel
解决语法转换、源代码转换。主要用于旧浏览器或者环境中将ECMAScript 2015+代码转换为向后兼容版本的 JavaScript
- 安装
1 2 3
| npm install @babel/cli #babel的核心代码 npm install @babel/plugin-transfor-arrow-functions -D # 箭头函数转换的插件 npm install @babel/plugin-transform-block-scoping -D # 用于const,let转为var
|
- 使用
1
| npx babel src --out-dir dist --plugins=@babel/plugin-transform-block-scoping,@babel/plugin-transform-arrow-functions
|
- src:是源文件的目录
- –out-dir:指定要输出的文件夹dist
预设preset
- 安装
1
| npm install @babel/preset-env -D
|
- 使用
1
| npx babel src --out-dir dist --presets=@babel/preset-env
|
babel-loader
搭配在webpack中使用
- 安装依赖
1
| npm install babel-loader @babel/core
|
- 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| module: { rules: [ { test: /\.js$/, use: { loader: "babel-loader", options: { plugins: [ "@babel/plugin-transform-arrow-functions", "@babel/plugin-transform-block-scoping" ] } } } ] }
|
如果一个个配置babel的插件显然不合理,我们可以使用babel-preset,webpack会根据我们的预设来加载对应的插件列表,并且将其传递给babel。
- 安装
1
| npm install @babel/preset-env
|
- 配置
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| module: { rules: [ { test: /\.js$/, use: { loader: "babel-loader", options: { presets: [ "@babel/preset-env" ] } } } ] }
|
babel可以放在独立的配置文件
在根目录新建.babel.config.json
1 2 3 4 5
| module.exports = { presets: [ ["@babel/preset-env"] ] }
|
vue-loader
用来处理.vue文件
- 安装
1
| npm install vue-loader -D
|
- 配置
1 2 3 4
| { test: /\.vue$/, loader: "vue-loader" }
|
- 还需要添加@vue/compiler-sfc来对template进行解析
1
| npm install @vue/compiler-sfc -D
|
1 2 3 4
| const { VueLoaderPlugin } =require("vue-loader/dist/index"); plugins: [ new VueLoaderPlugin() ]
|
本地服务器
当文件发生变化时,可以自动的完成编译 和展示
webpack watch mode
- 可以在
webpack.config.js
中加入watch:true
- 或者在
package.json
文件中加入脚本
1 2 3
| "scripts": { "watch": "webpack --watch", }
|
webpack-dev-serve
用于实时重新加载
- 安装
1
| npm install webpack-dev-serve -D
|
- 配置
1 2 3
| devServer: { hot: true, },
|
Proxy配置选项可以解决跨域访问问题
请求先发送到一个代理服务器,代理服务器和API服务器没有跨域的问题,就可以解决我们的跨域问题了
设置选项
- target:表示的是代理到的目标地址,比如 /api/moment会被代理到 http://localhost:8888/api/moment
- pathRewrite:默认情况下,我们的 /api 也会被写入到URL中,如果希望删除,可以使用pathRewrite
- secure:默认情况下不接收转发到https的服务器上,如果希望支持,可以设置为false
resolve模块解析
1 2 3 4 5 6
| resolve: { extensions: [".js", ".json", ".jsx", ".ts", ".vue"], alias: { "@": path.resolve(__dirname, "./src") } },
|