theme: channing-cyan
一.创建项目
废话不多说,直接开始初始化一个weboack的项目
yarn init -y yarn add webpack webpack-cli --dev
项目目录:
二.测试
新建一些文件夹和文件按,随便写点东西
```html // src/index.js console.log("webpack");
// index.html
Hello, world!
用live server
打开 html:
三.利用 webpack 打包
npx 可以让我们直接运行nodemodules下库的自带命令行,而不用写 nodemodules下的相对路径 npx webpack
打包完成后,可以看到项目中多了一个 dist 目录:
四.写点内容
接下来,首先修改一下 index.html
文件, 方便后面使用打包后使用的js文件 ```html
Hello, world!
```
在 src/data.js
export function getBlogPosts() { return ['博客1', '博客2', '博客3'] }
修改index.js 内容,添加打印 博客数据的代码 ```js import { getBlogPosts } from './data';
console.log(getBlogPosts()); 完事后,执行`npx webpack`,可以看到,打包后的js文件内容
js (()=>{"use strict";console.log(["博客1","博客2","博客3"])})(); ``` 很明显简化了console的内容,还对代码进行了压缩,说明webpack,智能的判断了代码的逻辑。
在回到浏览器,查看
控制台打印了三个博客列表的数据
五.webpack配置文件
webpack 最核心的就是它的配置文件啦~,文档都有写的很详细,可以修改入口文件
、配置出口
、通过 loader
加载不同的文件,在通过 plugins
,在打包过程提供一些代码优化或者是其他的操作,现在我们来测试一下,看看把打包后的文件名修改一下:
新建 webpack.config.js
```js const path = require('path');
module.exports = { mode: "development", // 模式 开发/生产 entry: "./src/index.js", // 入口 output: { // 出口 filename: "dist.js", // 打包文件 path: path.resolve(__dirname, "dist"), // 打包文件路径 }, }; `` 执行
npx webpack,dist目录下就多了一个
dist.js` 文件,打开可以看到
接下来,修改
index.html
```html
``` 那么之前的 main.js ,就不需要了,我们删除就好了。
六.使用loader来加载css文件,图片文件以及静态资源
修改index.js
,根据获取出来的博客列表的数据,来生成一组ul>li元素展示 ```js import { getBlogPosts } from './data';
const blogs = getBlogPosts(); const ul = document.createElement('ul'); blogs.forEach((blog) => { const li = document.createElement('li'); li.innerText = blog; ul.appendChild(li); }) document.body.appendChild(ul); `` 执行
npx webpack`,回到页面:
新建 src/style.css
,写一点简单css代码调整一下: ```css * { margin: 0; padding: 0; box-sizing: border-box; font-family: sans-serif; list-style: none; }
body { display: grid; place-items: center; }
li { padding: 12px;
}
img { max-width: 500px; } 回到 `src/index.js`,导入刚写的css文件
js ... import "./style.css";
.. `` 我们先不使用 loader,执行
npx webpack`来打包看看
这里直接报错了,意思是我们需要一个合适的 loader 来处理这个文件类型,当前,没有配置加载程序来处理此文件。
那么,加载 css 文件,那么我们需要安装两个 loader
yarn add --dev style-loader css-loader
安装完成后,我们需要在 webpack.config.js
去配置一下: ```js const path = require('path');
module.exports = { ...
//
module: {
rules: [{
test: /\.css$/i,
use: ["style-loader", "css-loader"],
}]
}
}; `` 执行
npx webpack,看到控制台输出
successfully`,回到页面
可以看到,css样式就应用上了。
那么如何,加载图片呢,对于图片和一些静态资源,webpack 原生支持,就不需要额外安装对应的 loader 了,直接在 webpack.config.js
配置一下: js ... module: { rules: [{ test: /\.css$/i, use: ["style-loader", "css-loader"], },{ test: /\.(png|svg|jpg|jpeg|gif)$/i, type: "asset/resource", } ] } };
回到 index.js
,把图片导入,写点js代码把图片添加到页面上: ```js ...
import CoderImage from "./assets/images/coder.jpg";
...
const image = document.createElement('img'); image.src = CoderImage; document.body.prepend(image); `` 执行
npx webpack`, 回到页面查看,图片就显示到页面上啦。
七.使用 html-webpack-plugin
安装 html-webpack-plugin
yarn add html-webpack-plugin --dev
安装好后,来到 webpack.config.js
,添加一下配置 ```js ... const HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = { ... plugins: [new HtmlWebpackPlugin()], }; `` 执行
npx webpack,可以看到
dist目录下生成了一个
index.html` 文件:
html <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>Webpack App</title> <meta name="viewport" content="width=device-width, initial-scale=1"><script defer src="dist.js"></script></head> <body> </body> </html>
打开到浏览器上看一看,可以看到效果是一样的
可以看到这个 html 的标题是默认的
回到 webpack.config.js
, js plugins: [new HtmlWebpackPlugin({ title: "博客列表", })],
执行npx webpack
,可以看到就修改掉了
八.使用 babel-loader
如果是低版本的浏览器,那么就不得不得做兼容,比如,es6的代码就得转成 es5 等等.
安装 babel-loader 相关依赖 yarn add --dev babel-loader @babel/core @babel/preset-env
回到 webpack.config.js
, js ... module.exports = { mode: "development", // 方便看打包后的代码 devtool: "inline-source-map", ... module: { rules: [ ... { test: /\.js$/, exclude: /node_modules/, use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"], }, } } ] }, };
写好以上配置后,执行npx webpack
打包命令,可以看到把我们之前写的 ES6
的语法转成了 ES5
匿名函数的形式,说明babel-loader
就生效了。
九.使用 terser-webpack-plugin
一个很常见的应用场景,我们在开发完项目后,需要打包项目,压缩代码,减少后的文件体积。
安装 terser-webpack-plugin
yarn add --dev terser-webpack-plugin
回到 webpack.config.js
, ```js ... const TerserWebpackPlugin = require('terser-webpack-plugin');
... // 优化 optimization: { minimize: true, // 是否要压缩 minimizer: [new TerserWebpackPlugin()], // 使用什么缩工具 }, `` 执行
npx webpack打包命令, 查看
dist/dist.js`
代码被压缩了,之前的空格也没有了,后面还有很长的一段加密字符。
十.使用 webpack-dev-server
现在,我们需要在开发的时候,每次要改动的js之后都要重新打包,这样会比较繁琐,webpack 提供了 webpack-dev-server
开发服务器,它可以在启动之后,如果我们修改的是js代码,它就重新打包并刷新页面,现在我们来看一看吧~
安装 yarn add --dev webpack-dev-server
```js ...
... devServer: { static: "./dist", }, ... 然后来到 `package.json`,来配置一个启动命令:
json ... "scripts": { "start": "webpack serve --open" }, ... 然后在 `Terminal` 里面输入
yarn start `` 这样 webpack 就会启动
webpack-dev-server`,自动打开页面展示和之前的效果。
现在,我们随便在index.js
新增点内容,再来看看效果 js ... const h1 = document.createElement('h1'); h1.innerText = "博客列表"; document.body.prepend(h1);
可以看到h1
标签就添加进来了
现在我们打包后的文件,这个 dist.js 的文件名每次都是一样的,但是浏览器会根据文件名进行缓存,一般我们为了避免浏览器会缓存,我们会给文件名添加一串随机的字符,每次更新之后都改为新的字符,那么webpack也支持自动在打包后生成新的一串字符。
我们来看一看怎么来实现。
回到 webpack.config.js
,修改一下配置: js output: { // filename: "dist.js", filename: "[name].[contenthash].js", }
然后终止服务器运行,在运行 npx webpack
打包,可以看到生成的文件后就带有生成随机的字符串的文件名
我们再来index.js
, 随便注释一段代码: js // const h1 = document.createElement('h1'); // h1.innerText = "博客列表"; // document.body.prepend(h1);
再来打包观察:
这里也生成了新的随机字符串的文件,我们删除这四个文件,把上面注释的代码解开,在回到 webpack.config.js
文件,修改回去。
十一.配置别名
接下来,我们来设置设置一下别名,有时候我们在开发的过程中,文件嵌套的可能会比较深,要引入其他目录下的 js 文件,需要使用很多../../../ ....
来访问这个文件的路径,webpack 可以让我们指定一个文件别名,来把这一串相对路径,替换掉,这样就可以少些一些字符串.
在webpack.config.js
,添加一下配置: js resolves: { alaias: { 'xxx', path.resolve(__dirname, "src/xxx"), } }
十二.使用 bundle-analyzer
有时候,我们可能需要打包后分析打包后的结果,哪个文件占的体积比较大,需要下一步的优化。webpack 也有一个可视化的打包分析工具,叫做 webpacl-bundle-analyzer
安装 js yarn add --dev webpack-bundle-analyzer
在webpack.config.js
,添加一下配置: ``` const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
...
// 插件 plugins: [ ... new BundleAnalyzerPlugin(), ], ```
执行 npx webpack
,打包命令,就会自动打开到浏览器可视化展示:
可以看到 index.js
是体积最大的,这样就很直观分析了。
十三.总结
webpack 是很多构建工具的基础,它的出现改变了传统前端项目的开发方式,形成了工程化。
webpack 是什么,为什么要用 Webpack,webpack 的 loader 和 plugins 的使用方法等。
webpack 的知识太多了,本文只列举了常用的 loader 和 plugins,道路且长~
webpack.config.js ```js const path = require('path'); const HtmlWebpackPlugin = require('html-webpack-plugin'); // 用于创建 HTML 页面并自动引入 JS 和 CSS const TerserWebpackPlugin = require('terser-webpack-plugin'); // 压缩打包后的文件 const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; //分析打包后体积较大的可视化插件
module.exports = { mode: "development", // 模式 development, production 或 none devtool: "inline-source-map", // 方便看打包后的代码 entry: "./src/index.js", // 入口 output: { // 出口 filename: "dist.js", // 打包文件 // filename: "[name].[contenthash].js", // 生成带有随机字符的文件 path: path.resolve(dirname, "dist"), // 打包文件路径 }, // 解析 resolve: { alias: { // utils: path.resolve(dirname, "src/utils"), } }, // 优化 optimization: { minimize: true, // 是否要压缩 minimizer: [new TerserWebpackPlugin()], // 使用什么缩工具 }, devServer: { static: "./dist", }, // 插件 plugins: [new HtmlWebpackPlugin({ title: "博客列表", }), new BundleAnalyzerPlugin(), ], // 模块 module: { rules: [{ // 匹配规则 test: /.css$/i, use: ["style-loader", "css-loader"], // 使用工具 }, { test: /.(png|svg|jpg|jpeg|gif)$/i, type: "asset/resource", // webpack 自带静态资源打包类型 }, { test: /.js$/, exclude: /node_modules/, // 排除 不进行打包 use: { loader: "babel-loader", options: { presets: ["@babel/preset-env"], }, } } ] }, }; ```
十四.参考
webpack中文文档:https://webpack.docschina.org/