Webpack知识体系 | 青训营笔记

62 阅读2分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 12 天

什么是Webpack

问题

文件管理依赖手动管理:

  • 多个JS文件,操作复杂
  • 文件代码产生依赖时要严格按照顺序书写
  • 开发与生产环境不一致
  • 资源管理模型不一致
  • 难以接入Less等工具…

工程化工具 => “前端工程”

Webpack

  • 本质上是一种前端资源编译、打包工具
  • 功能化中枢、工作流中的一个步骤
  • 实现模块化和一致性

使用Webpack

步骤

  • 安装 npm i -D webpack webpack-cli
  • 编辑配置文件 webpack.config.js
  • 执行编译命令 npx webpack

核心流程

  • entry Get Start入口处理,启动编译流程
  • require importDependencies Lookup 依赖解析,找到资源
  • module Transform根据module配置进行资源解析,调用资源转移器,将非标准JS资源转译为JS
  • 依赖和资源解析递归调用,直到所有资源处理完毕
  • output Combine Assets 资源合并打包,成为可以直接在浏览器上运行的JS文件

配置

Webpack 的使用方法,基本围绕"配置"展开

  • 流程类:作用于流程中的某些环节,直接影响打包效果的配置项
  • 工具类:主流程之外,提供更多工程化能力的配置项

image.png

例子

Loader处理css文件

  • npm add -D css-loader style-loader
 const path = require('path')
 ​
 module.exports = {
     entry: './src/index.js',  // 入口文件(必须)
     mode: 'development', // 生产模式
     output: { // 输出(必须)
         filename: '[name].js',
         path: path.join(__dirname, 'dist')
     },
     module: {
         rules: [{  // 用两个loader处理css文件
             test: /.css$/,
             use: ['style-loader', 'css-loader']
         }]
     }
 }

思考:

  • Loader的作用是什么?为什么需要用到css-loader,style-loader
  • 这种方式与在HTML中维护css相比,有什么优劣之处?
  • 如何在Webpack中接入Less, Sess, Stylus这类css预编译框架?

答:理解Loader

接入Babel

  • 将高版本的代码(如ES6)转为低版本代码(ES5)
  • npm i -D @babel/core @babel/perset-env babel-loader
 const path = require('path')
 ​
 module.exports = {
     entry: './src/index.js', 
     mode: 'development', 
     output: { 
         filename: '[name].js',
         path: path.join(__dirname, 'dist')
     },
     module: {
         rules: [{
             test: /.js$/,
             use: [{
                 loader: 'babel-loader',
                 options: [
                     ['@babel/preset-env']
                 ]
             }]
         }]
     }
 }

生产HTML

  • npm i -D html-webpack-plugin
 const path = require('path')
 const HtmlWebpackPlugin = require('html-webpack-plugin')
 ​
 module.exports = {
     entry: './src/index.js',  
     mode: 'development', 
     output: {
         filename: '[name].js',
         path: path.join(__dirname, 'dist')
     },
     plugins: [new HtmlWebpackPlugin]  // 插件
 }

HMR

  • 模块替换Hot Module Replacemant
  • 配置项devServer:{hot:true}
  • 启动Webpack:npx webpack serve

Tree-Shaking

  • Dead Code
    • 没有被用到的代码
    • 代码执行结果不会被用到……
  • 本质是删除Dead Code
  • 对工具类库如Lodash,其能删除很多不必要的工具
 module.exports = {
     entry: './src/index.js',  
     mode: 'production',   // mode
     devtool:false,
     output: {
         filename: '[name].js',
         path: path.join(__dirname, 'dist')
     },
     optimization: {
         usedExports: true
     },   
 }

理解Loader

只做一件事情:内容转换,设计来处理非标准JS资源,用于将这些资源翻译为标准JS

Loader链式调用

  • less-loader:实现less=> 转换为css
  • css-loader:将css包装为符合JS语法的模块
  • style-loader:将css模块包装到require语句内

image.png

常见Loader

image.png

理解插件

插件是什么?为什么这样设计?

没有插件, 整个项目过于复杂

  • 新人需要了解整个流程甚至细节,上手成本高
  • 功能迭代成本高,牵一发动全身,可维护性低
  • 功能僵化,作为开源项目则缺乏成长性,生命力弱

插件架构的精髓:

  • 只实现最核心的功能,只做好主流程
  • 思想:对扩展开发,对修改封闭