美文网首页
Webpack 学习笔记

Webpack 学习笔记

作者: _于曼丽_ | 来源:发表于2022-04-07 19:37 被阅读0次

概念

参考文档

构建

将源代码转化为分发代码的过程称为构建。

  • 源代码:用于书写和编辑的代码
  • 分发代码:在构建过程中,经过最小化和优化后产生的输出结果,最终将在浏览器中加载

打包

根据依赖图将多个模块的代码合并到一个或者几个 chunk 中的过程称为打包。

模块

一个文件就是一个模块,模块可以是任何类型的文件,原生支持 js 和 json 文件,其他类型的文件需要使用对应的 loader 转换成 js 文件。

chunk 组

module.exports = {
  entry: {
    home: './home.js',
    about: './about.js',
  },
};

chunk 组:每个键值对就是一个 chunk 组。以上配置包括两个 chunk 组:home 组 about 组。
每个 chunk 组至少包括一个 initial chunk,以及零个或者多个 non-initial chunk。

chunk

chunk: 一个导出的 js 文件就是一个 chunk,一个 chunk 中的代码可以包括多个模块。

initial chunk

根据入口模块的依赖图打包形成的 bundle 称为 initial chunk,有几个入口模块就生成几个 initial chunk。

entry 指定入口模块
output.filename 指定 initial chunk 的名称

non-initial chunk:

non-initial chunk 包括 async chunk 和 split chunk:

  • import() 导入的模块,根据该模块的依赖图打包形成一个 async chunk。通过注释指定 async chunk 的 name import(/* webpackChunkName: 'foo' */'./foo')
  • 通过 splitChunks 从一个 initial chunk 或者一个 async chunk 中分离出 split chunk,例如 vendor common runtime 等 chunk。

output.chunkFilename 指定 non-initial chunk 的名称。

模块解析规则

模块的依赖关系

模块之间存在依赖关系,通过以下方式来表明依赖关系,根据依赖关系绘制依赖图。

js 文件中:
import
require
import()

css 文件中:
@import
url()

html 文件中:
<img src="">

模块的路径解析

模块的路径有三种表达方式:

  • 绝对路径:不要使用
  • 相对路径:在代码中引入自定义的模块(js 模块、css、img 等资源等)
  • 模块路径:在代码中引入第三方模块,在配置文件中配置 loader

当使用模块路径的时候,优先使用 resolve.alias 设置的模块别名的路径来解析模块,如果没有对应的模块别名,再根据模块解析的步骤来解析模块路径。

// 第三方模块使用模块路径
import _ from 'lodash'
// 自己的模块使用相对路径
import sum from './vendor/sum.js'
import './css/style.css'
import Icon from './images/icon.png'
// js 文件可以省略扩展名,推荐不要省略
import sum from './vendor/sum'

// 动态引入模块可以使用相对路径、绝对路径和模块路径
import('./vendor/sum.js')
import('lodash')

通过 css-loader 可以将 css 文件中的 url() 理解为模块依赖,引入图片等资源,推荐使用相对路径

.hello {
  background: url('../images/icon.png') no-repeat;
}

通过 html-loader 可以将 html 文件中的 img src="" 理解为模块依赖,引入图片等资源,推荐使用相对路径

<img src="./images/icon.png">

entry 的路径解析

entry 可以是相对路径,也可以是模块路径,相对路径相对于 context 选项,该选项默认值为配置文件所在的目录。

module.exports = {
  // context 必须是绝对路径
  context: path.resolve(__dirname),
  entry: {
   // 相对路径,相对 context 选项
   index: './src/index.js',
   // 模块路径,根据模块的解析规则来解析
   vendor: 'lodash'
  }
};

loader 的路径解析

loader 可以是相对路径、绝对路径、模块路径,解析规则与模块的解析规则一样。

module: {
  rules: [
    test: /\.css$/,
    // 推荐使用模块路径
    use: ['style-loader', 'css-loader']              
  ]
}

其他知识点

runtime 和 manifest

runtime 和 manifest 都是 webpack 生成的内容,每次打包 runtime 和 manifest 都不同,为了缓存,应该将 runtime 和 manifest 分离出来。

  • manifest 是数据,保留原始的各个模块的信息。
  • runtime 是 webpack 生成的代码

runtime 根据 manifest,将源代码中 import 和 require 都转换为 __webpack_require__(module identifier)

缓存

生产模式下,推荐 bundle 文件名 filename: [name].[contenthash].js,contenthash 可以保证一旦更新模块,则生成的包会重新下载。

process.env.NODE_ENV

参考文档

在 package.json 中

{
  "scripts": {
    "build": "NODE_ENV=production webpack",
    "dev": "NODE_NEV=development webpack serve --open"
  }
}

在 webpack.config.js 中的 process.env.NODE_ENV 访问的是通过命令行传入的参数 NODE_ENV,也就是 package.json 文件中 scripts 里面定义的 NODE_ENV 的值。

const webpack = require('webpack');

// 这里的值是通过命令行传入的参数值,如果是 npm run build,则值为 production。
console.log(process.env.NODE_ENV)

module.exports = {
    entry: {
        app: './src/app'
    },
    output: {
        path: 'dist',
        filename: 'bundle.js'
    },
    plugins: [
        new webpack.DefinePlugin({
            // 这里定义了可以在模块中访问的 process.env.NODE_ENV 的值
            'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV)
        })
    ]
};

在模块中访问的 process.env.NODE_ENV 其实是在配置文件中通过 DefinePlugin 定义的值,而不是通过命令行传入的值。

将配置文件的 mode 设置为 development 或者 production,相当于自动通过 DefinePlugin 定义了可以在模块中访问的 process.env.NODE_ENV 为 mode 的值。

相关文章

网友评论

      本文标题:Webpack 学习笔记

      本文链接:https://www.haomeiwen.com/subject/vgarsrtx.html