Webpack | 青训营笔记

67 阅读4分钟

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

Webpack

01 入门应用

理解打包流程

熟练掌握常用配置项、Loader、插件的使用方法,能够灵活搭建集成 Vue、React、Babel、Eslint、Less、Sass、图片处理等工具的 Webpack 环境

掌握常见脚手架工具的用法,例如:Vue—cli、create—react—app、@angular/cli

02 进阶

理解 Loader、Plugin 机制,能够自行开发 Webpack 组件

理解常见性能优化手段,并能用于解决实际问题

理解前端工程化概念与生态现状

03 大师级

阅读源码,理解 Webpack 编译、打包原理,甚至能够参与共建

简介

用vue项目来举例: 浏览器它是只认识js,不认识vue的。而我们写的代码后缀大多是.vue的,在每个.vue文件中都可能html、js、css甚至是图片资源;并且由于组件化,这些.vue文件之间还有错综复杂的关系。所以项目要被浏览器识别,我们就要使用webpack将它们打包成js文件以及相应的资源文件。

或者这么理解,我们以vue项目的形式编写项目逻辑,浏览器以他理解的方式来运行项目。webpack把我们的vue项目想表达的所有意图传递给浏览器让浏览器去运行。

Webpack的运行需要依赖Node.js

使用:安装——配置——执行

使用

入口处理——从entry开始启动编译流程

依赖解析——从entry开始,根据import等找到依赖

资源解析——根据module配置,将png、css等非标准JS资源转译为JS内容

资源合并——将转义后的资源文件合并打包为可直接在浏览器中运行的JS文件

vue-cli 配置 package.json

vue-cli自带webpack。

在package.json中,不仅可以记录安装的内容,还可编写脚本。注意看package.json中的“scripts”配置项。

// 这是package.json
{
  "name": "zhihu_demo",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "build": "webpack --config webpack.config.js"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/rehellinen/zhihu_demo.git"
  },
  "author": "",
  "license": "ISC"
}

配置 webpack.config.js

webpack.config.js文件是webpack的默认配置文件。之前我们使用命令行$ webpack entry.js output.js来实现打包,其实webpack可以有更多的打包配置,这些配置都是在webpack.config.js中完成的。下面是一个简单的webpack.config.js。

const webpack = require("webpack")
​
module.exports = {
  entry: {
    entry: "./app/entry.js",
  },
  output:
  {
    path: __dirname + "/dist",
    filename: 'bundle.js',
  },
  devtool: false,
  devServer:{
    hot:true,
    open:true
  },
  module: {
    loaders: [
      {
        test: /.js$/,
        loader: 'babel',
        exclude: /node_modules/
      },
      {
        test: /.sass$/,//处理sass后缀的文件
        exclude: /node_modules/,
        use: [
          'style-loader',
          'css-loader',
          'sass-loader'//用了这三个来处理
        ]
      }
    ]
  },
  plugins: [
    // 该插件用于把新生成js自动部署到html中
    new HtmlWebpackPlugin({
      // 指明该插件需要处理的html模版
      template: path.resolve(__dirname, './index.html') 
    })
    // 该插件清除上次残留的文件
    new CleanWebpackPlugin() 
  ]
}

entry

entry是配置webpack的入口文件,上面的代码中我们将app目录下的entry.js作为入口文件。webpack会将与entry.js有关的资源都进行打包。

一般一个html页面对应一个入口。webpack将从入口js文件开始一步步分析该页面,只要是页面用到的文件(包括图片和样式文件等等),都会被转成对应的js文件。

output

Webpack将打包后的文件将输出到哪里。

loaders

loader是webpack的加载器,可以帮我们处理各种非js文件,转换为js。如css样式,vue、jsx、weex等后缀的代码,JPG、PNG图片等。所以我们一般会在package.json中看到各种***-loader。这些就是各类资源的loader加载器。

在module的loaders数组中可以有多个对象,每个对象就是一个加载器。最重要的就是text属性和use属性

一些loader

jscsshtmlassets
babel-loadercss-loaderhtml-loaderfile-loader
eslint-loaderstyle-loaderpug-loaderval-loader
ts-loaderless-loaderposthtml-loaderurl-loader
buble-loadersass-loaderjson5-loader
vue-loaderstylus-loader
postcss-loader

babel——转译ES6代码。webpack打包的文件默认是不支持ES6的,我们需要用babel转译。在webpack.config.js中添加babel-loader的配置

sass-loader——处理 Scss 文件。在配置 Scss 文件的处理规则时,设置 rule 对象的 use 属性为 ['style-loader', 'css-loader', 'sass-loader'] 即可。

  • sass-loader:sass转为css
  • css-loader:css包装成module.exports = "${css}"的符合js的格式
  • style-loader:把css包入require语句,并用injectstyle等注入到页面的style标签

思考:与在html中使用css相比,使用loader有何优劣?

plugins

很多知名工具都设计了所谓”插件“架构。因为功能很多很复杂,了解这个流程细节的上手成本高。所以插件——对扩展开放,对修改封闭

插件可以扩展webpack的功能,让webpack不仅仅是完成打包,甚至各种更复杂的功能,或者是对打包功能进行优化、压缩,提高效率。

插件用起来还是简单,但是问题是要搞懂插件内部的配置

插件举例

html-webpack-plugin

平时打包过程中,除了HTML文件外的其它文件都被打包了,当在线上部署时,我们还得自己复制HTML到dist,然后手动添加生成的js到HTML中,这非常不友好。

可以用它生成一个index.html,其中已经自动添加了当前目录下的build.js

HotModuleReplacementPlugin

模块热更新插件。Hot-Module-Replacement 的热更新是依赖于 webpack-dev-server,后者是在打包文件改变时更新打包文件或者 reload 刷新整个页面,HRM 是只更新修改的部分。

HotModuleReplacementPluginwebpack模块自带的,所以引入webpack后,在plugins配置项中直接使用即可。

DashboardPlugin

devtool

在webpack中新增一行 devtool: eval-source-map , 将会生成source-map 供浏览器展示,信息写到源文件bundle.js里

将配置修改为devtool: source-map,重新打包后,则会生成独立的source-map文件

devServer

hot设置为true就自动更新

watch

持续看代码

mode

用development的话,会全部导入编译

用production,且optimization的usedExperts为true,一些不被使用的变量等就不被引入了,相当于tree-shaking。没用的代码就不打包,产物就会变得很小了

optimization

打包之后

打包完成就会出现一个在 dist 目录下有一个 bundle.js 文件。

有了打包文件,我们还需要创建一个 index.html 。创建一个id为app的div元素用于显示Vue组件内容,然后将打包好的bundle.js引用进去。

现在,到项目目录中找到 index.html 页面,我们就可以像打开静态网页一样打开我们完成的项目。

又可能出现引用资源的路径问题,我们需要修改一下项目目录下的config文件夹里的index.js中的assetsPublicPath