webpack是什么
webpack是一个项目构建工具、它可以把你一些组织互相依赖的代码、按类别去帮你打包成一个整体唯一的文件、在打包中通过loader去处理webpack不认识的文件、在打包构建流程中抛出不同时期的生命周期钩子通知plugin、也可以在打包中往代码里面注入不同的环境变量、对代码的压缩配合其他插件(babel) 对源代码进行编译、编译成通用浏览器的语法、也可以在plugin里面对输出文件内容的做增删除、最重要的是这一系列的流程你并不需要写太多代码、你只需通过一个配置文件去定义你的打包规则、相对来说比较简单就能配置出一个基础环境!
webpack特点
- 自身功能齐全、插件系统完善支持自定义loader和plugin、定制化强、扩展性强、面对复杂场景也是游刃有余、社区生态完整、业界应用工程化首选!
搭建一个简单的webpakc环境
安装webpack依赖
// 初始化package.jsonyarn init// 安装webpackyarn add webpack webpack-cli -D// 在package.json里面配置打包命令"scripts": {"build":"webpack --config webpack.config.js"}
创建webpack.config.js(打包配置文件)
```javascript // 根节点创建webpack.config.js const path = require(‘path’);
module.exports = { // 入口文件 entry: { ‘main’:’./src/main.js’, }, // 此选项控制是否生成,以及如何生成 source map。 devtool: ‘inline-source-map’, // 模式-环境 mode: ‘development’, module:{ // 模块配置相关(配置 loader、解析器等选项) rules:[
]},// 插件使用plugins: [],// 输出规则output: {// 输出的文件名、[name] 来自打包的名称filename: '[name].bundle.js',// 输出的位置path: path.resolve(__dirname, 'dist'),// 在生成文件之前清空 output 目录clean: true}
};
> 创建一个src->main.js、然后在src下在创建一个test1.js 和test2.js、然后开始随便写点内容、下方的图就是依赖关系<a name="wXcSD"></a>#### 执行yarn build 开始打包> 打包后我们在根节点创建一个public文件夹、并且里面创建一个index.html引入dist里面的js文件,然后在浏览器打开、我们发现里面输出了我们打包文件的内容信息、这样我们就完成了一个简单的打包!下面我们开始配置一些常用的loader和插件<a name="vh3r3"></a>#### 常用loader和plugin<a name="IqXhZ"></a>##### loader- **style-loader、css-loader **```javascript// 安装yarn add style-loader css-loader -D// webpack.config.js使用module: {// 模块配置相关(配置 loader、解析器等选项)rules: [{test: /\.css$/i,use: ["style-loader", "css-loader"],},]}// 使用import "./style/common.css"
- file-loader、raw-loader、url-loader ```javascript // 安装 yarn add file-laoder
// webpack.config.js使用 module.exports = { module: { // 模块配置相关(配置 loader、解析器等选项) rules: [ { test: /.(png|jpe?g|gif)$/i, use: [ { loader: ‘file-loader’ } ] } ] } }
// 使用 import icon from “./assets/icon02.png”
- **babel-loader** ( 将高级语法转义成低版本浏览器也能认识的插件)```javascript// 安装babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime -D// webpack.config.js使用module.exports = {module: {// 模块配置相关(配置 loader、解析器等选项)rules: [{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],plugins: ['@babel/plugin-transform-runtime']}}}]}}// 使用// test1.jsexport const fn = async () =>{const res = await asyncTest()console.log('function',res)}function asyncTest(){return new Promise( resolve =>{setTimeout( () =>{resolve(1111)},2000)})}// main.jsimport { fn } from "./test1.js"const mains = "main.js"console.log(test1)fn()
plugin
- UglifyJsPlugin 压缩和混淆代码 ```javascript // 安装 yarn add uglifyjs-webpack-plugin -D
// webpack.config.js使用 const UglifyJsPlugin = require(‘uglifyjs-webpack-plugin’); module.exports = { optimization: { minimizer: [ new UglifyJsPlugin({ cache: true, parallel: true }) ] } }
- **html-webpack-plugin **自动生成html、并引用打包后的js```javascript// 安装yarn add html-webpack-plugin -D// webpack.config.js使用const HtmlWebpackPlugin = require('html-webpack-plugin')module.exports = {plugins: [new HtmlWebpackPlugin()]}
- webpack-bundle-analyzer 打包分析插件、可以分析你的打包内容所消耗的时间、根据各种维度去分析进行优化打包速度 ```javascript // 安装 yarn add webpack-bundle-analyzer -D
// webpack.config.js使用 const BundleAnalyzerPlugin = require(‘webpack-bundle-analyzer’).BundleAnalyzerPlugin; module.exports = { plugins: [ new BundleAnalyzerPlugin() ] }
// 执行build后会自动打开分析的html文件
- **optimize-css-assets-webpack-plugin** 不同组件中重复的css可以快速去重- **happypack** 通过多进程模型,来加速代码构建<a name="dkGrk"></a>### 贴上整体基础配置文件```javascriptconst path = require('path');const UglifyJsPlugin = require('uglifyjs-webpack-plugin');const HtmlWebpackPlugin = require('html-webpack-plugin')const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;module.exports = {// 入口文件entry: {'main': './src/main.js',},// 此选项控制是否生成,以及如何生成 source map。devtool: 'inline-source-map',// 模式-环境mode: 'development',module: {// 模块配置相关(配置 loader、解析器等选项)rules: [{test: /\.css$/i,use: ["style-loader", "css-loader"],},{test: /\.(png|jpe?g|gif)$/i,use: [{loader: 'file-loader',}]},{test: /\.m?js$/,exclude: /(node_modules|bower_components)/,use: {loader: 'babel-loader',options: {presets: ['@babel/preset-env'],plugins: ['@babel/plugin-transform-runtime']}}}]},optimization: {minimizer: [new UglifyJsPlugin({cache: true,parallel: true})],splitChunks: {// 抽离入口文件公共模块为commmons模块cacheGroups: {commons: {name: "commons",chunks: "initial",minChunks: 2}}}},// 插件使用plugins: [new HtmlWebpackPlugin(),new BundleAnalyzerPlugin()],// 输出规则output: {// 输出的文件名、[name] 来自打包的名称filename: '[name].bundle.js',// 输出的位置path: path.resolve(__dirname, 'dist'),// 在生成文件之前清空 output 目录clean: true}};
webpack构建流程
我们在学习了webpack基础打包配置后、现在我们还需要学习下webpack构建的整个流程是什么样的、了解其基本的构建过程有助于我们更熟悉webpack、今后使用webpack更能知道那个环节可以优化和排查问题! 下面贴一张网上找的图片、个人觉得写的很清晰!可以先看图了解下整个过程!
一、合并参数
启动打包后、webpack会把默认配置和用户自定义的配置( webpack.config.js ) 进行参数配置合并、得到最终的options对象给到下一个流程!!
二、实例化Compiler和订阅生命周期
合并完配置对象后、准备初始化compiler对象、该对象是继承至Tapabel、给所有的插件注册生命周期的订阅、然后执行run方法开始执行编译!
三、parser分析项目依赖
找到入口文件、开始分析文件构建AST树、找出依赖递归下去处理、依赖递归根据文件类型去命中相对应的loader配置、调用配置中的所有loader对文件进行transformation
四、输出文件
递归完所有的依赖后、就能拿到每个文件结果、根据entry的配置或者分包配置生成对应的chunk文件
本篇package.json版本
{"name": "webpack-cli-test","version": "1.0.0","main": "index.js","license": "MIT","scripts": {"build": "webpack --config webpack.config.js"},"devDependencies": {"@babel/core": "^7.17.8","@babel/plugin-transform-runtime": "^7.17.0","@babel/preset-env": "^7.16.11","babel-loader": "^8.2.4","css-loader": "^6.7.1","file-loader": "^6.2.0","html-webpack-plugin": "^5.5.0","style-loader": "^3.3.1","uglifyjs-webpack-plugin": "^2.2.0","webpack": "^5.71.0","webpack-bundle-analyzer": "^4.5.0","webpack-cli": "^4.9.2"}}
