常见基础问题(webpack、vite篇二)

196 阅读2分钟

如何提高 webpack 构建速度?

  1. 使用 DllPlugin 将不常变化的代码提前打包,并复用,如 vue、react
  1. 使用 thread-loader 或 HappyPack(过时)进行多线程打包
  1. 处于开发环境时,在 webpack config 中将 cache 设为 true,也可用 cache-loader(过时)
  1. 处于生产环境时,关闭不必要的环节,比如可以关闭 source map

参考文档


webpack 与 vite 的区别是什么?

  1. 开发环境区别

    1. vite 自己实现 server,不对代码打包,充分利用浏览器对 <script type=module> 的支持

      1. 假设 main.js 引入了 vue
      1. 该 server 会把 import { createApp } from 'vue' 改为 import { createApp } from "/node_modules/.vite/vue.js" 这样浏览器就知道去哪里找 vue.js 了
    1. webpack-dev-server 常使用 babel-loader 基于内存打包,比 vite 慢很多很多很多

      1. 该 server 会把 vue.js 的代码(递归地)打包进 main.js
  1. 生产环境区别

    1. vite 使用 rollup+ esbuild来打包 JS 代码
    1. webpack 使用 babel来打包 JS 代码,比 esbuild 慢很多很多很多。

      1. webpack 能使用 esbuild 吗?可以,你要自己配置(很麻烦)。
  1. 文件处理时机

    1. vite 只会在你请求某个文件的时候处理该文件
    1. webpack 会提前打包好 main.js,等你请求的时候直接输出打包好的 JS 给你

目前已知 vite 的缺点有:

  1. 热更新常常失败,原因不清楚
  1. 有些功能 rollup 不支持,需要自己写 rollup 插件
  1. 不支持非现代浏览器(如ie)

webpack 怎么配置多页应用?

对应的 webpack config:

const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  entry: {
    app: './src/app.js',
    admin: './src/admin.js',
  },
  plugins: [
    new HtmlWebpackPlugin({
      filename: 'index.html',
      chunks: ['app']
    }),
    new HtmlWebpackPlugin({
      filename: 'admin.html',
      chunks: ['admin']
    })
  ],
};

但是,这样配置会有一个「重复打包」的问题:假设 app.js 和 admin.js 都引入了 vue.js,那么 vue.js 的代码既会打包进 app.js,也会打包进 admin.js。我们需要使用 optimization.splitChunks 将共同依赖单独打包成 common.js(HtmlWebpackPlugin 会自动引入 common.js)。

如何支持无限多页面呢?

写点 Node.js 代码来实现

const HtmlWebpackPlugin = require('html-webpack-plugin');
const fs = require('fs')
const path = require('path')

const filenames = fs.readdirSync('./src/pages')
  .filter(file => file.endsWith('.js'))
  .map(file => path.basename(file, '.js'))

const entries = filenames.reduce((result, name) => (
  { ...result, [name]: `./src/pages/${name}.js` }
), {})
const plugins = filenames.map((name) =>
  new HtmlWebpackPlugin({
    filename: name + '.html',
    chunks: [name]
  })
)

module.exports = {
  entry: {
    ...entries
  },
  plugins: [
    ...plugins
  ],
};

swc、esbuild 是什么?

swc

实现语言:Rust

功能:编译 JS/TS、打包 JS/TS

优势:比 babel 快很多很多很多(20倍以上)

能否集成进 webpack:能

使用者:Next.js、Parcel、Deno、Vercel、ByteDance、Tencent、Shopify……

做不到:

  1. 对 TS 代码进行类型检查(可以先用其他的,如 tsc 检查)。
  1. 打包 CSS、SVG

esbuild

实现语言:Go

功能:同上

优势:比 babel 快很多很多很多很多很多很多(10~100倍)

能否集成进 webpack:能

使用者:vite、vuepress、snowpack、umijs、blitz.js 等

做不到:

  1. 对 TS 代码进行类型检查
  1. 打包 CSS、SVG