1️⃣ Webpack 出入口配置所需 node 知识点

模块化代码中, 比如 require(“./“), 表示当前 js 文件所在的目录
在路径处理中, “./“ 表示 node 运行目录
__dirname : 所有情况下, 都表示当前运行的 js 所在的目录, 它是一个绝对路径
path 对象

  1. // 该对象提供了大量的路径处理函数
  2. var path = require("path"); // 导出一个对象
  3. // 可以将所有字符串拼成一个绝对路径
  4. var result = path.resolve("./", "a", "b", "c"); // node 运行目录\a\b\c
  5. // 也可以使用 __dirname
  6. var result = path.resolve(__dirname, "src")

1️⃣ Webpack 入口配置

  1. module.exports = {
  2. // ========== 配置入口 ===========
  3. // >>> string 形式
  4. // >>>>>> 单入口, 打包形成一个chunk, 输出一个 bundle 文件, 此时 chunk 的名称默认是 main
  5. entry: './src/index.js',
  6. // >>> array 形式
  7. // >>>>>> 多入口, 所有入口文件最终只会形成一个 chunk, 输出出去只有一个 bundle 文件
  8. // >>>>>> 作用: 只有在 HMR 功能中让 html 热更新生效
  9. entry: ['./src/index.js', './src/one.js'],
  10. // >>> object 形式
  11. // >>>>>> 多入口: 有几个入口文件就形成几个 chunk, 同时输出出去就有几个 bundle 文件, 此时 chunk 的名称是 key
  12. // >>>>>> 作用: 只有在 HMR 功能中让 html 热更新生效
  13. entry: {
  14. main: "./src/index.js", // 键: chunk名 值: 入口模块
  15. one: "./src/one.js"
  16. },
  17. // >>> 特殊用法
  18. entry: {
  19. main: "./src/index.js",
  20. one: ["./src/one.js", "./src/two.js"]
  21. },
  22. }

2️⃣ context

context: path.resolve(__dirname, "./src")
该配置会影响入口和 loaders 的解析,入口和 loaders 的相对路径会以 context 的配置作为基准路径,这样,你的配置会独立于 CWD(current working directory 当前执行路径)

  1. module.exports = {
  2. // 可以让入口或 loader 配置少写一个开头或者说给入口或者 loader 配置, 写一个默认开头, 所有入口文件和 loader 配置均以 "./src" 开头
  3. entry: '/index.js',
  4. context: path.resolve(__dirname, "./src")
  5. }

1️⃣ Webpack 出口配置

filename: 'js/[name].[chunkhash:5].js' 可以在名字前加上文件夹的名字让文件打包到指定的文件夹

  1. module.exports = {
  2. // ========== 配置输出地址 ==========
  3. output: {
  4. // ---------- 配置输出地址 ----------
  5. // >>> 配置输出文件输出的文件地址 ( 将所有资源打包输出到的文件夹 ), 必须配置一个绝对路径
  6. path: path.resolve(__dirname, 'builder'), // 将所有资源打包输出到 builder 文件里 ( 不配置默认为 dist 文件 )
  7. // ---------- 配置打包后的 js 文件名 ----------
  8. // >>> 静态规则
  9. filename: 'jsPackName.js', // 打包后的 js 文件名为 jsPackName.js
  10. // >>> 动态规则
  11. // >>>>>> [name]: 在入口为多入口时 [name] 会在输出时替换为 chunk名, [name] 想要生效如果必须以对象的形式配置
  12. // >>>>>> [hash]: 取 hash 作为名字一部分的原因是, 浏览器会有缓存, 当浏览器生成缓存后, 如果文件名不变浏览器始终会使用缓存的 js 文件, 如果使用 hash 当文件内容有变化时, 最终打包生成的 js 文件的名字也会变化, 这样在内容更新后,浏览器请求时发现文件名不同, 就会重新请求 js 文件就不会使用缓存的文件了
  13. // >>>>>>>>> [hash:5]: 取最终的 hash 值前 5 位( 缺点: 如果统一使用最终的 hash 那么只要有一个文件有所变化所有的文件名都会变化, 浏览器则需要请求所有的 js 文件 )
  14. // >>>>>>>>> [chunkhash:5]: 取各自 chunk 的 hash 前 5 位( 优点: 各自的 js 文件使用各自的 hash 值, 文件内容更新只会影响自己的文件名, 不会影响其他的文件名, 浏览器不会重新请求不需要请求的文件 )
  15. filename: '[name].[chunkhash:5].js', // 打包后的 js 文件名为 [chunk名].[总的hash名的前5位].js
  16. // ---------- 所有资源在引入时的公共路径前缀 - 一般用于生产环境 ----------
  17. // 在出口处配置会影响所有用到 publicPath 的 loader 如果 loader 用到的路径不同应当配置在自己 loader 里
  18. publicPath: './',
  19. // ---------- js 暴露的全局赋值给谁 ----------
  20. libraryTarget: 'window', // 变量名添加到 window 上
  21. // libraryTarget: 'global', // 变量名添加到 global 上
  22. // libraryTarget: 'commonjs', // 变量名添加到 commonjs 上
  23. },
  24. }

2️⃣ library

**library: "one"**
这样一来,打包后的结果中,会将自执行函数的执行结果暴露给 abc

  1. module.exports = {
  2. entry: '/index.js',
  3. context: path.resolve(__dirname, "./src")
  4. output: {
  5. path: path.resolve(__dirname, 'dist'),
  6. library: "one"
  7. }
  8. }

image.png
image.png

2️⃣ libraryTarget

  1. module.exports = {
  2. entry: '/index.js',
  3. context: path.resolve(__dirname, "./src")
  4. output: {
  5. path: path.resolve(__dirname, 'dist'),
  6. library: "one",
  7. libraryTarget: "var"
  8. }
  9. }

该配置可以更加精细的控制如何暴露入口包的导出结果
其他可用的值有:

  1. 1. var:默认值,暴露给一个普通变量
  2. 2. window:暴露给 window 对象的一个属性
  3. 3. this:暴露给 this 的一个属性
  4. 4. global:暴露给 global 的一个属性
  5. 5. commonjs:暴露给 exports 的一个属性
  6. 6. 其他:[https://www.webpackjs.com/configuration/output/#output-librarytarget](https://www.webpackjs.com/configuration/output/#output-librarytarget)

1️⃣ 入口和出口的最佳实践

2️⃣ 一个页面一个JS

image.png

3️⃣ 源码结构

  1. |—— src
  2. |—— pageA 页面A的代码目录
  3. |—— index.js 页面A的启动模块
  4. |—— ...
  5. |—— pageB 页面B的代码目录
  6. |—— index.js 页面B的启动模块
  7. |—— ...
  8. |—— pageC 页面C的代码目录
  9. |—— main1.js 页面C的启动模块1 例如:主功能
  10. |—— main2.js 页面C的启动模块2 例如:实现访问统计的额外功能
  11. |—— ...
  12. |—— common 公共代码目录
  13. |—— ...

3️⃣ webpack 配置

  1. module.exports = {
  2. entry:{
  3. pageA: "./src/pageA/index.js",
  4. pageB: "./src/pageB/index.js",
  5. pageC: ["./src/pageC/main1.js", "./src/pageC/main2.js"]
  6. },
  7. output:{
  8. filename:"[name].[chunkhash:5].js"
  9. }
  10. }

这种方式适用于页面之间的功能差异巨大、公共代码较少的情况,这种情况下打包出来的最终代码不会有太多重复

2️⃣ 一个页面多个JS

image.png

3️⃣ 源码结构

  1. |—— src
  2. |—— pageA 页面A的代码目录
  3. |—— index.js 页面A的启动模块
  4. |—— ...
  5. |—— pageB 页面B的代码目录
  6. |—— index.js 页面B的启动模块
  7. |—— ...
  8. |—— statistics 用于统计访问人数功能目录
  9. |—— index.js 启动模块
  10. |—— ...
  11. |—— common 公共代码目录
  12. |—— ...

3️⃣ webpack 配置

  1. module.exports = {
  2. entry:{
  3. pageA: "./src/pageA/index.js",
  4. pageB: "./src/pageB/index.js",
  5. statistics: "./src/statistics/index.js"
  6. },
  7. output:{
  8. filename:"[name].[chunkhash:5].js"
  9. }
  10. }

这种方式适用于页面之间有一些独立、相同的功能,专门使用一个 chunk 抽离这部分 JS 有利于浏览器更好的缓存这部分内容。

2️⃣ 单页应用

所谓单页应用,是指整个网站(或网站的某一个功能块)只有一个页面,页面中的内容全部靠JS创建和控制。 vue和react都是实现单页应用的利器。
image.png

3️⃣ 源码结构

  1. |—— src
  2. |—— subFunc 子功能目录
  3. |—— ...
  4. |—— subFunc 子功能目录
  5. |—— ...
  6. |—— common 公共代码目录
  7. |—— ...
  8. |—— index.js

3️⃣ webpack 配置

  1. module.exports = {
  2. entry: "./src/index.js",
  3. output:{
  4. filename:"index.[hash:5].js"
  5. }
  6. }