驾驭webpack系列二:提升篇

1,716 阅读4分钟

小知识,大挑战!本文正在参与“程序员必备小知识”创作活动

本文同时参与 「掘力星计划」   ,赢取创作大礼包,挑战创作激励金

前言

承接上一篇webpack基础篇,这一节我们将带领大家在webpack添加处理图片的功能区分生产环境,开发环境,讲解devtool的配置打包编译前清理dist目录PostCSS 处理浏览器兼容问题eslint配置,使我们的webpack初具规模。本期的源码地址请参考webpack02

结尾有彩蛋哦😝


构建过程


处理图片文件

在项目中我们经常会用到图片,无论是css中url()引入图片,还是在js中import图片,图片功能是必不可少的。图片有很多常用的格式png,jpg,gif等,接下来我们就用添加loader的功能来让webpack去打包图片。是的,我们只要添加一个处理图片的 loader 配置就可以让webpack支持图片打包

--> 图片常用到的loader有两个file-loader,url-loader,下面是两个loader的介绍

file-loader:当引入的文件是 .png、.txt 等时,可以通过 file-loader 解析项目中的 url 引入。根据配置将文件拷贝到相应的路径,并修改打包后文件的引入路径,让它指向正确的文件。

url-loader:url-loader 封装了 file-loader 且可以不依赖于 file-loader 单独使用,并且可以配置 limit。对小于 limit 大小的图片转换成 Base64,大于 limit 的时候使用 file-loader 里的方法。

首先安装

yarn add url-loader file-loader --dev

对webpack.config.js进行配置,在rules中增加

 {
        test: /\.(jpg|png|gif)$/,
        use: [
          {
            loader: "url-loader",
            options: {
              limit: 2 * 1024,
              name: "[name].[contenthash:8].[ext]",
              outputPath: "assets/images",
            },
          },
        ],
 }
  • "[name].[contenthash:8].[ext]":表示输出的hash值,主要用于解决引用图片的缓存问题
  • outputPath:输出图片的路径
  • limit:url-loader具有file-loader的全部功能,下面的options中的操作过程是,把10k以内的图片打包成base64的文件,用来减少http请求,大于2k的图片,还是使用file-loader,大多数项目中base64的大小一般都是2k,因为base64的体积往往是图片体积的4/3,太大的话base64会比图片大出很多,性能上会有影响

devtool配置

为什么需要使用devtool

为什么呢?因为通常我们运行在浏览器中的代码是经过处理的,处理后的代码可能与开发时代码相差很远,这就导致开发调试和线上排错变得困难。这时Source Map就登场了,有了它浏览器就可以从转换后的代码直接定位到转换前的代码。在webpack中,可以通过devtool选项来配置Source Map。

如何配置效率更高,更好

在大多数项目中,开发环境使用的是eval-cheap-module-source-map,这样打包速度也会快一些。而生产环境这边多大数只需要知道报错的模块和行号就可以了,所以使用的是nosources-source-map就可以了

区分开发/生产环境

为什么要区分生产环境和开发环境

因为生产环境要有利于开发和调试,尽可能快的构建开发包,所以可以在开发环境中打包.map文件用于调试;但是在生产环境中就不要打包map文件了,会增大生产包体积,牺牲性能,生产环境应该尽可能压缩,优化bundle文件,以最小的体积,最快的速度进行展示。

首先安装

yarn add webpack-merge --dev

在根目录新建config文件

再把以前配置的webpack.config.js文件取名为webpack.base.config.js并放到config文件中

在config中新建webpack.dev.config.js(开发环境打包文件)和weback.prod.config.js(生产环境打包文件)文件

目录如下

image.png 开发环境

const { merge } = require("webpack-merge");
const base = require("./webpack.base.config");

module.exports = merge(base, {
  mode: "development",
});

生产环境

const { merge } = require("webpack-merge");
const base = require("./webpack.base.config");

module.exports = merge(base, {
  mode: "production",
});

虽然都分开了配置,但是在公共配置中,还是可能会出现某个配置的某个选项在开发环境和生产环境中采用不同的配置,我们可以通过设置process.env.Node_ENV也就是通过设置当前node环境来区分开发环境还是生产环境,但是还有个问题,window和mac或者liunx他们设置node环境的命令不一样,为了使命令统一,我们可以使用cross-env来设置,他具有跨平台设置环境变量的功能

yarn add cross-env

安装以后,我们可以在package.json中这样配置script

image.png

我们现在就使用这个环境变量做点事吧!记得之前配的公共配置中,我们给出口文件的名字配了 hash:8 ,原因是在生产环境中,即用户已经在访问我们的页面了,他第一次访问时,请求了比如 app.js 文件,根据浏览器的缓存策略会将这个文件缓存起来。然后我们开发代码完成了一版功能迭代,涉及到打包后的 app.js 发生了大变化,但是该用户继续访问我们的页面时,如果缓存时间没有超出或者没有人为清除缓存,那么他将继续得到的是已缓存的 app.js ,这就糟糕了。

于是,当我们文件加了 hash 后,根据入口文件内容的不同,这个 hash 值就会发生非常夸张的变化,当更新到线上,用户再次请求,因为缓存文件中找不到同名文件,就会向服务器拿最新的文件数据,这下就能保证用户使用到最新的功能。

不过,这个 hash 值在开发环境中并不需要,于是我们修改 webpack.base.config.js 文件:

const isDev = process.env.NODE_ENV !== "production";
module.exports = {
  ...,
  output: {
    filename: `js/[name]${isDev ? "" : ".[hash:8]"}.js`,
    path: path.join(__dirname, "../dist"),
  },
 ...
};

打包编译前清理dist目录

我们打包的时候,经常每次打包都要先把dist目录删除,在打新的包,那么有没有什么办法在打包之前,让webpack给我们自动清除dist目录呢,答案是当然后,webpack非常贴心的提供了此项服务,只要使用clean-webpack-plugin插件就可以了

yarn add clean-webpack-plugin --dev

只需要在plugins里面加入如下代码就可以生效

plugins: [

   new CleanWebpackPlugin(),

],

PostCSS 处理浏览器兼容问题

像flex等css属性经常会遇到浏览器兼容性问题,这节我们就用postcss来处理浏览器兼容性问题

首先讲解一下postcss是干什么的,postcss 一种对 css 编译的工具,类似 babel 对 js 一样通过各种插件对 css 进行处理,在这里我们主要使用以下插件:

  • postcss-preset-env :将最新的 CSS 语法转换为目标环境的浏览器能够理解的 CSS 语法,目的是使开发者不用考虑浏览器兼容问题。
yarn add postcss-loader postcss-preset-env --dev

图片.png

只是这样配置还是不能生效的,还需要我们在package.json中配置browserslist

像下面这样

{
 ...
  "browserslist": [
    "defaults",
    "not ie < 11",
    "last 2 versions",
    "> 1%",
    "iOS 7",
    "last 3 iOS versions"
  ],
 ...
}

这是配置的浏览器兼容性列表,这样配置以后就可以完美的生效了

eslint配置

为了保证大家书写代码的规范性,eslint是工程化中不可或缺的一环

首先进行安装

eslint lint代码的主要工具,所以的一切都是基于此包 
babel-eslint 该依赖包允许你使用一些实验特性的时候,依然能够用上Eslint语法检查。反过来说,当你代码并没有用到Eslint不支持的实验特性的时候是不需要安装此依赖包的。 
pre-commit 钩子在commit提交信息前运行 
lint-staged 用于对 Git 暂存区中的文件执行代码检测
yarn install eslint babel-eslint pre-commit lint-staged --dev

配置文件.eslintrc.js参考

module.exports = {
  root: true,
  env: {
    browser: true,
    es6: true,
    node: true,
  },
  extends: "eslint:recommended",
  parser: "babel-eslint",
  rules: {
    "no-console": process.env.NODE_ENV === "production" ? "error" : "off",
    "no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
    "space-before-function-paren": 0,
  },
};

package.json配置参考

"scripts": {
    "lint:staged": "lint-staged"
  },
  "lint-staged": {
      "src/**/*.{ts,js}": [
        "eslint --fix"
      ]
  },
  "pre-commit": "lint:staged",

这样eslint就可以生效了

非常感谢大家能看到这里,辛苦啦,缓解缓解眼疲劳,欣赏美女的微笑,😝

image.gif

感觉程序员应该很少看电视把,大家知道这个美女是谁么❓ 欢迎评论区留言👏🏻

今天这篇文章已经丰富了我们的webpack功能,下节将带领大家去用webpack构建react,并完善开发环境和生产环境配置,加油,感恩!!!

参考文章