Система длинных текстов 4D разбирает основы Webpack (посередине)

Webpack
Система длинных текстов 4D разбирает основы Webpack (посередине)

разделение кода

  Разделение кода (code splitting)ДаwebpackУникальная технология, которая может разделить код по определенной форме, вместо того, чтобы загружать все сразу, а загружать по запросу, может эффективно уменьшить размер загружаемых ресурсов на первом экране.

CommonsChunkPlugin

  CommonsChunkPluginдаwebpack4-Встроенный плагин может объединять несколькоchunkизвлечено из публичной части. Тем самым уменьшая повторную упаковку модулей в процессе разработки и повышая скорость разработки. Общий размер ресурса также уменьшается, и можно эффективно использовать кеш клиента.

  CommonsChunkPluginНастраиваемые свойства следующие.

  • name:будетchunksатрибут, соответствующийsource chunkОбщие модули в извлечении дляnameв, если не указаноchunks, который будет извлекаться по умолчаниюentry chunksпубличные модули в
  • chunks: уточнитьsource chunk, то есть из которогоchunkНайти общие модули в, опуская этот параметр по умолчаниюentry chunks
  • filename: имя извлеченного файла ресурсов, которое поддерживает динамическую генерацию в виде языка шаблонов.
  • minChunks: может быть числом, функцией илиInfinity

Упаковка без плагинов

  Корневой каталог включаетpackage.json,webpack.config.jsиsrcЖдать,srcкаталог включаетfoo.js,bar.jsиutils.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^3.10.0"
  },
  "dependencies": {
    "jquery": "^3.2.1"
  }
}

// webpack.config.js
module.exports = {
    entry: {
        foo: './src/foo.js',
        bar: './src/bar.js'
    },
    output: {
        filename: './dist/[name].js'
    }
}

// src/bar.js
import jquery from 'jquery'
import { log } from './utils.js'

console.log(jquery, log, 'bar')

// src/foo.js
import jquery from 'jquery'
import { log } from './utils.js'

console.log(jquery, log, 'foo')

// src/utils.js
export function log(){
    console.log('log')
}

   После запуска пакета он окажется в корневом каталогеdistсоздание папкиbar.jsиfoo.jsjqueryиutilsупакованы в эти два файла.

在这里插入图片描述

   Наконец, вам нужно добавить на страницуscriptЗнакомство с этикеткойfoo.jsиbar.js.

// src/index.html
<html lang="zh-CN">
  ...
  <body>
    <script src="./bar.js"></script>
    <script src="./foo.js"></script>
  </body>
</html>

Извлечь общедоступный код

Исправлятьwebpack.config.js, добавлятьCommonsChunkPluginПлагины извлекают общие модули.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    foo: "./src/foo.js",
    bar: "./src/bar.js",
  },
  output: {
    filename: "./dist/[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js",
    }),
  ],
}

следующееfoo.jsиbar.jsсторонние модули вjqueryи публичные модули внутри проектаutils,webpackВсе запущенные файлы упакованы вvendor.js,foo.jsиbar.jsОбъем значительно уменьшается.

在这里插入图片描述

страницаvendor.jsбыть в другомjsимпортировал раньше.

// dist/index.js
<html lang="zh-CN">
  ...
  <body>
    <script src="./vendor.js"></script>
    <script src="./bar.js"></script>
    <script src="./foo.js"></script>
  </body>
</html>

Извлечь время выполнения

   При использовании плагина для извлечения общедоступных модулей извлекаемые ресурсы включают не только код модуля, но иwebpackВремя выполнения.webpackСреда выполнения относится к коду, который инициализирует среду, например, создание объектов кэша модуля, объявление функций загрузки модуля и т. д.

   Первый нижеCommonsChunkPluginэкземпляр будет извлеченfoo.jsиbar.jsсторонние модули вjquery, локальный модульutilsиwebpackфайл времени выполнения вvendorсередина.

   и следующийCommonsChunkPluginпример сноваvendorИзвлеките файлы среды выполнения вruntimeсредний, финальныйvendorвключает сторонние модулиjqueryи локальные модулиutils,runtimeсодержитwebpackфайл времени выполнения.

УведомлениеruntimeизCommonsChunkPluginдолжен появиться вpluginsНаконец, иначеwebpackМодуль не будет извлечен нормально.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    foo: "./src/foo.js",
    bar: "./src/bar.js",
  },
  output: {
    filename: "./dist/[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js",
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "runtime",
      filename: "./dist/[name].js",
      chunks: ["vendor"],
    }),
  ],
}

   Выполнить пакет будет вdistсоздается в каталогеruntime.jsиrendor.jsи другие документы.

在这里插入图片描述

вышеpluginsЭквивалентно следующему способу.

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: ["vendor", "runtime"],
    filename: "./dist/[name].js",
  }),
]

   также можно сделать черезminChunksДля достижения цели извлечения файлов среды выполнения при настройкеminChunksзаn, это означает, что модуль может быть толькоnКусокchunksПри этом ссылка будет извлечена,CommonsChunkPluginПо умолчанию две записи обращаются только к одному модулю.chunkСсылка будет извлечена, т.е.minChunkПо умолчанию2.

Установить какInfinityУказывает, что порог извлечения бесконечно высок, т.е. все модули не будут извлечены.

Установить какInfinityКак правило, есть две функции, первая — разрешитьwebpackизвлекать только определенные модули, другой — генерировать модуль без каких-либо модулей, а только содержащийwebpackфайл времени выполненияruntime.

  Следующие средства от входаchunkизвлеките файлы среды выполнения изfooиbarИзвлечь сторонние модули и локальныеutilsмодуль.

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: "runtime",
    filename: "./dist/[name].js",
    minChunks: Infinity,
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: "vendor",
    filename: "./dist/[name].js",
    chunks: ["foo", "bar"],
  }),
]

Извлечение сторонних модулей и локальных модулей

первыйCommonsChunkPluginпримерminChunksУстановить какInfinity, что означает, что все модули не будут извлечены, в это времяnameУстановить какruntimeможно извлечьwebpackфайл времени выполнения. Однако из-заnameНазначенvendorvendorна входеentryЭто заявлено вvendorМодуль, соответствующий массиву (jquerywebpackфайл времени выполнения.

   разCommonsChunkPluginпример изvendorизвлеченный изwebpackфайл времени выполнения, на этот разvendorсодержит только сторонние модулиjquery,runtimeсодержит файлы времени выполнения.

последнийCommonsChunkPluginПример последний изfooиbarизвлеките локальный модуль вutilsсередина.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    foo: "./src/foo.js",
    bar: "./src/bar.js",
    vendor: ["jquery"],
  },
  output: {
    filename: "./dist/[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js",
      minChunks: Infinity,
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "runtime",
      filename: "./dist/[name].js",
      chunks: ["vendor"],
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "utils",
      filename: "./dist/[name].js",
      chunks: ["foo", "bar"],
    }),
  ],
}

   Выполнить пакет будет вdistсоздается в каталогеvendor.js,utils.jsиruntime.js.

在这里插入图片描述

вышеpluginsЭквивалентно следующему способу.

plugins: [
  new webpack.optimize.CommonsChunkPlugin({
    name: ["vendor", "runtime"],
    filename: "./dist/[name].js",
    minChunks: Infinity,
  }),
  new webpack.optimize.CommonsChunkPlugin({
    name: "utils",
    filename: "./dist/[name].js",
    chunks: ["foo", "bar"],
  }),
]

   Другой способ — использоватьminChunksфункция, где перваяCommonsChunkPluginпримерminChunksв функции,module.resourceполный путь, включая имя модуля,countКоличество обращений к модулю путем обхода входного файла и зависимых от него модулей, если модуль находится вnode_modules, он будет извлечен вvendor, по существу такой способ позволяетvendorСохраняются только сторонние модули.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    foo: "./src/foo.js",
    bar: "./src/bar.js",
  },
  output: {
    filename: "./dist/[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js",
      minChunks: function(module, count) {
        return module.resource && module.resource.includes("node_modules")
      },
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "runtime",
      filename: "./dist/[name].js",
      chunks: ["vendor"],
    }),
    new webpack.optimize.CommonsChunkPlugin({
      name: "utils",
      filename: "./dist/[name].js",
      chunks: ["foo", "bar"],
    }),
  ],
}

Страница    относится к каждомуjsСпособ следующий.

<html lang="zh-CN">
  ...
  <body>
    <script src="./runtime.js"></script>
    <script src="./utils.js"></script>
    <script src="./vendor.js"></script>
    <script src="./foo.js"></script>
    <script src="./bar.js"></script>
  </body>
</html>

Одностраничное приложение, извлекающее сторонние модули

   Одностраничное приложение может создать отдельную запись следующим образомvendorСодержит сторонние модулиvueиwebpackфайл времени выполнения.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    main: "./src/main.js",
    vendor: ["vue"],
  },
  output: {
    filename: "./dist/[name].js",
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js",
    }),
  ],
}

   финал после упаковкиdistсоздается в каталогеmain.jsиvendor.js.

在这里插入图片描述

   Цитируется на страницеjsСпособ следующий.

<html lang="zh-CN">
  ...
  <body>
    <script src="./vendor.js"></script>
    <script src="./main.js"></script>
  </body>
</html>

Асинхронная загрузка ресурсов

  Когда количество модулей слишком велико, а объем ресурсов слишком велик, некоторые временно неиспользуемые модули загружаются с задержкой. Сделайте ресурсы, загружаемые при первом отображении страницы, как можно меньше, а последующие модули будут ждать, пока не наступит нужное время, чтобы инициировать загрузку.Этот метод является загрузкой по запросу.

  webpackОфициально рекомендуетсяimportфункция для асинхронной загрузки модуля и возвратаPromiseобъект.

   Следующий корневой каталог включаетwebpack.config.jsиsrcпапки и т. д., гдеsrcвключить нижеmain.js,utils.js,main.jsпрошедшийimportАсинхронная загрузкаutils.js.

// src/main.js
setTimeout(() => {
  import(/* webpackChunkName: "utils-chunk" */ "./utils.js")
}, 2000)
console.log("main")

// src/utils.js
import jquery from "jquery"

console.log(jquery, "utils")

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./dist/[name].js",
    chunkFilename: "./dist/[name].js",
    publicPath: "../",
  },
}

  output.chunkFilenameИспользуется для указания асинхронногоchunkИмя файла, способ поддержки языка шаблона, асинхронностьchunkПо умолчанию имя отсутствует, его значение по умолчанию равно[id].js,как0.js,1.jsЖдать.

пройти черезwebpackВсе уникальные аннотации позволяютwebpackполучить асинхронныйchunkимя, как в предыдущем/* webpackChunkName: "utils-chunk" */, после упаковкиchunkимяutils-chunk.

   После упаковкиmain.jsВ качестве загружаемого ресурса на первом экране страница проходитscriptтеги для ссылки, в то время как косвенные ресурсы (utils-chunk.js) запросить путь для прохожденияoutput.publicPathуказать.

在这里插入图片描述

На страницу    ссылаются следующим образом.

<html lang="zh-CN">
  ...
  <body>
    <script src="./main.js"></script>
  </body>
</html>

  2sпозже на страницеheadДинамическая вставка внутри этикеткиscriptэтикетка, ссылка на этикеткуutils-chunk.js.

在这里插入图片描述

optimization.splitChunks

  CommonsChunkPluginОбщие модули могут быть извлечены во многих сценариях, но их дефекты также очень очевидны.

  • не замужемCommonsChunkPluginЭкземпляры могут извлекать только одинvendor, чтобы извлечь несколькоvendorНужно добавить большеCommonsChunkPluginнапример, легко вызвать дублирование кода конфигурации
  • несколькоCommonsChunkPluginМежду экземплярами может существовать логическая связь. Только правильная логическая связь может гарантировать, что извлеченный код соответствует ожидаемому, а некоторые конфигурации непросты для понимания и не могут быть использованы «из коробки».

  webpack4удаленCommonsChunkPlugin, улучшенCommonsChunkPluginИ переработана и реализована функция фрагментации кода, готовая к прохождениюoptimization.splitChunksсвойства для упрощения настройки разделения кода.

Извлечь общедоступный код

будетwebpackобновление версии, даCommonsChunkPluginИзмените сценарий упаковки асинхронных ресурсов наsplitChunks,регулироватьwebpack.config.js.

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "[name].js",
  },
  optimization: { splitChunks: { chunks: "all" } },
  mode: "none",
}

// package.json
{
  ...
  "devDependencies": {
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3"
  }
}

   Результат запуска пакета следующий, гдеmain.jsиutils.jsупакованы индивидуально,utils.jsсторонние модули, упомянутые вjqueryбыл упакован вvendors~utils-chunk.js.

在这里插入图片描述

   ссылка на страницуmain.jsЗадний,2sпозже на страницеheadВставьте внутрь этикеткиvendors~utils-chunk.jsиutils-chunk.js, количество параллельных запросов в это время равно2.

  CommonsChunkPluginСцена не извлеченаutilsсерединаjqueryмодуль, если только модифицироватьutilsВ одной строке кода клиенту достаточно повторно загрузить весьutils-chunk.js. иsplitChunksИзвлекатьjqueryмодуль,jqueryне будет часто меняться, модифицироватьutilsВ одной строке кода клиенту нужно только повторно скачатьutils-chunk.js, а размер этого файла всего1 KiBнет, иvendor~utils-chunk.jsОн также хорошо использует кэширование браузера.

在这里插入图片描述

Условия экстракции

  CommonsChunkPluginИзвлечение конкретных модулей через элементы конфигурации ближе к императиву. иsplitChunksРазница в том, что задаются только некоторые условия извлечения, такие как объем модуля, расположение модуля и т.д. Когда некоторые модули удовлетворяют этим условиям, они будут автоматически извлечены, что ближе к декларативному.splitChunksУсловия извлечения по умолчанию следующие.

  • извлеченchunkотnode_modulesкаталог, вnode_modulesМодули, как правило, являются общими модулями, которые больше подходят для извлечения.
  • извлеченjavascript chunkбольше, чем30KB,CSS chunkбольше, чем50KB, объем ресурсов после извлечения, как правило, слишком мал, и эффект оптимизации, вызванный этим, также относительно общий.
  • В процессе загрузки по требованию максимальное значение ресурсов, запрошенных параллельно, меньше или равно5
  • При загрузке в первый раз максимальное количество ресурсов, запрошенных параллельно, меньше или равно3

Извлечь несколько асинхронных ресурсов

  Корневой каталог включаетwebpack.config.jsиsrcпапка,srcвключить нижеmain.jsиfoo.js,bar.js.

// src/main.js
setTimeout(() => {
  import(/* webpackChunkName: "bar-chunk" */ "./bar.js")
  import(/* webpackChunkName: "foo-chunk" */ "./foo.js")
}, 2000)
console.log("main")

// src/bar.js
import react from "react"

console.log(react, "bar")

// src/foo.js
import vue from "vue"
import react from "react"

console.log(vue, react, "foo")

   После запуска пакетаwebpackсоздастvueкодовый блок (vendor~foo-chunk),foo-chunkЗависит от этого блока кода и также создает содержащийreactкодовый блок (vendors~bar-chunk~foo-chunk),foo-chunkиbar-chunkЗависит от этого блока кода.

在这里插入图片描述

существуетimport('./bar.js)При вызове,vendors~bar-chunk~foo-chunk.jsиbar-chunk.jsЗагружать параллельно. существуетimport('./foo.js)При вызове,vendor~foo-chunk.jsиfoo-chunk.jsПараллельная загрузка, в данный момент загружать не нужноvendors~bar-chunk~foo-chunk.js, вы можете напрямую читать кеш.

在这里插入图片描述

Параметр конфигурации splitChunks

  webpackофициально даноsplitChunksЗначения по умолчанию следующие.

optimization: {
    splitChunks: {
      chunks: 'async',
      minSize: 30000,
      maxSize: 0,
      minChunks: 1,
      maxAsyncRequests: 5,
      maxInitialRequests: 3,
      automaticNameDelimiter: '~',
      name: true,
      cacheGroups: {
        vendors: {
          test: /[\\/]node_modules[\\/]/,
          priority: -10
        },
        default: {
          minChunks: 2,
          priority: -20,
          reuseExistingChunk: true
        }
      }
    }
}

chunks

  chunksНастраиваемыйsplitChunksрабочий режим, включая три необязательных значенияasync(дефолт),initial,allasyncт.е. извлекать только асинхронноchunk,initialИзвлечь только входящую синхронизациюchunk,allОба режима включены одновременно.

  Корневой каталог включаетwebpack.config.jsиsrc,srcвключить нижеmain.js,bar.jsиfoo.js.

// src/main.js
import jquery from "jquery"

setTimeout(() => {
  import(/* webpackChunkName: "bar-chunk" */ "./bar.js")
  import(/* webpackChunkName: "foo-chunk" */ "./foo.js")
}, 2000)
console.log(jquery, "main")

// src/bar.js
import react from "react"

console.log(react, "bar")

// src/foo.js
import vue from "vue"
import react from "react"

console.log(vue, react, "foo")

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "[name].js",
  },
  optimization: { splitChunks: { chunks: "all" } },
  mode: "none",
}

   После запуска пакетаmain.jsсторонние модули вjqueryизвлечено вvendor~main.js, остальные коды зарезервированы доmain.jsсередина,foo.jsсторонние модулиvueизвлечено вvendor~foo-chunk.js, оставшийся код зарезервирован доfoo-chunk.jsсередина,foo.jsиbar.jsсторонние модулиreactизвлечено вvendor~foo-chunk~bar-chunk.js,bar.jsОстальная часть кода зарезервирована доbar-chunk.js.

在这里插入图片描述

Исправлятьchunksсобственностьinitialснова упаковано, где толькоmain.jsсторонние модули вjqueryизвлечено вvendor~main.js, оставшийся код зарезервирован доmain.js,foo.jsиbar.jsСторонние модули вfoo-chunk.jsиbar-chunk.js.

在这里插入图片描述

ИсправлятьchunksсобственностьasyncПосле упаковки снова,main.jsСредний код зарезервирован до тех пор, покаmain.js, сторонние модули не извлекаются,foo.jsсторонние модули вvueизвлечено вvendor~foo-chunk.js, оставшийся код зарезервирован доfoo-chunk.js,foo.jsиbar.jsсторонние модулиreactизвлечено вvendor~bar-chunk~foo-chunk.js,bar.jsОставшийся код вbar-chunk.js.

在这里插入图片描述

условие совпадения

  • minSize: минимальный размер извлеченного блока кода перед сжатием, по умолчанию30000(30KB)
  • maxSize: максимальный размер извлеченного блока кода перед сжатием, по умолчанию0, т.е. неограниченный размер
  • minChunks: количество ссылок на модуль, по умолчанию1
  • maxAsyncRequests: максимальное количество загрузок по запросу, по умолчанию5
  • maxInitialRequests: максимальное количество начальных начальных загрузок, по умолчанию3
  • automaticNameDelimiter: извлеченный блок кода автоматически генерирует разделитель имен, по умолчанию ~
  • name: имя извлеченного файла блока кода, по умолчаниюtrue, то есть имя файла генерируется автоматически

группа кеша

  Группа кешаcacheGroupsПо умолчанию включаетvendorsиdefaultдва правила,vendorsдля добычиnode_modulesв подходящих модулях,defaultОн работает с модулями, на которые ссылаются несколько раз. Чтобы отключить определенное правило, вы можете напрямую установить его вfalse.

  cacheGroupsКаждый из них наследует или переопределяет внешнийsplitChunksзначения параметров в , например.cacheGroups.vendorsни один из предметовminChunksсвойство, оно унаследует внешнееsplitChunks.minChunksзначение атрибутаcacheGroups.vendors.minChunksза1.cacheGroups.defaultпредмет имеетminChunksсвойство, оно перезапишет внешнийsplitChunks.minChunksхарактеристики.

   Помимо указанных выше значений параметров,cacheGroupsПредусмотрены три дополнительных свойства конфигурации.

  • test: может соответствовать пути модуля илиchunkимя, по умолчанию для всех модулей
  • priority: указывает вес извлечения, чем выше значение, тем выше приоритет. Модуль может удовлетворять несколькимcacheGroups, который извлекается, контролируется наибольшим весом
  • reuseExistingChunk: использовать ли существующийchunk,trueзначит, если текущийchunkВключенные модули извлечены, новые создаваться не будут.

  Корневой каталог включаетwebpack.config.jsиsrcпапка,srcвключить нижеmain.jsиutils.js.

// src/main.js
import Vue from "vue"
import Vuex from "vuex"
import VueRouter from "vue-router"
import { log } from "./utils.js"

console.log(Vue, Vuex, VueRouter, log, "main")

// src/utils.js
export function log() {
  console.log("log")
}

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "[name].js",
  },
  optimization: {
    splitChunks: {
      chunks: "all",
    },
  },
  mode: "none",
}

   Запуск упакованного стороннего модуляvue,vuexиvue-routerизвлечено вvendors~main.js,main.jsоставшийся код иutils.jsкод зарезервирован доmain.jsсередина.

在这里插入图片描述

  Если вы хотите извлечь его отдельноutils.js, вы можете настроить его следующим образомcacheGroupsmodule.resourceполный путь, включая имя модуля.

// webpack.config.js
splitChunks: {
      chunks: "all",
      cacheGroups: {
        utils: {
          test: (module) => {
            return /src\\utils/.test(module.resource)
          },
          priority: -20,
          minSize: 0,
        },
        default: false,
      }
}

   Запуск упакованного стороннего модуляvue,vuex,vue-routerизвлечено вvendors~main.jsсередина,utils.jsКод извлекается вutils~main.jsсередина,main.jsОстальной код зарезервирован.

在这里插入图片描述

Производственная среда

  Производственная среда отличается от среды разработки.Производственная среда фокусируется на взаимодействии с пользователем, на том, как позволить пользователям быстрее загружать ресурсы, в том числе на том, как сжимать ресурсы, добавлять переменные среды для оптимизации упаковки и как максимально использовать кэши браузера.

Конфигурация среды

одиночная конфигурация

  Единая конфигурация, которая используется независимо от средыwebpack.config.js, просто передайте параметры переменных среды в начале сборки, а затемwebpack.config.jsКакая конфигурация используется, определяется условием.

УведомлениеwindowsНе поддерживается для использованияENV=developmentспособ, команда будет заблокирована и будет сообщено об ошибке, сторонние плагиныcross-envрешает эту проблему.

cnpm i cross-env --save-dev

  Корневой каталог включаетwebpack.config.jsиsrcпапки и т. д., гдеsrcвключить нижеindex.htmlиmain.js.

// package.json
{
  ...
  "scripts": {
    "dev": "cross-env ENV=development webpack-dev-server",
    "build": "cross-env ENV=production webpack"
  },
  "devDependencies": {
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3",
    "webpack-dev-server": "^3.1.14",
    "html-webpack-plugin": "^3.2.0"
  }
}

// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')

const ENV = process.env.ENV
const isProd = ENV === 'production'

module.exports = {
  entry: './src/main.js',
  output: {
    filename: isProd ? "./[name].[chunkhash:8].js" : "./[name].js",
  },
  plugins: [
    new HtmlWebpackPlugin({
      template: './src/index.html',
    })
  ]
}

// src/index.html
<html lang="zh-CN">

    <head>
        <title>hello world</title>
    </head>

    <body>
        <p>hello world</p>
    </body>
</html>

// src/main.js
console.log("hello world")

бегатьdevScript, консоль может просматривать упакованный выходной файл среды разработки.

在这里插入图片描述

бегатьbuildКоманда сценария для просмотра выходного файла после упаковки.

在这里插入图片描述

Конфигурация с несколькими средами

   Для каждой среды можно создать отдельный файл конфигурации, например, среда разработкиwebpack.dev.config.js, производственная средаwebpack.prod.config.js, но два конфигурационных файла обычно имеют повторяющиеся части, которые необходимо менять каждый раз при изменении, что не способствует сопровождению.

   также можно создать отдельныйwebpack.config.js, то два другихjsОбратитесь к этому файлу и добавьте конфигурацию своей среды. Но обычно используйте сторонние плагиныwebpack-merge, Привык делатьwebpackКонфигурация объединена для облегчения управления конфигурацией различных сред.

  Корневой каталогbuild,package.json,srcпапка,srcвключить нижеindex.htmlиmain.js.

// package.json
{
  ...
  "scripts": {
    "dev": "webpack-dev-server --config=./build/webpack.dev.config.js",
    "build": "webpack --config=./build/webpack.prod.config.js"
  }
}

  buildвключеныwebpack.config.js,webpack.dev.config.jsиwebpack.prod.config.js.

// build/webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
  entry: "./src/main.js",
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
}

// build/webpack.dev.config.js
const webpackConfig = require("./webpack.config.js")

module.exports = {
  ...webpackConfig,
  output: {
    filename: "./[name].js",
  },
}

// build/webpack.prod.config.js
const webpackConfig = require("./webpack.config.js")

module.exports = {
  ...webpackConfig,
  output: {
    filename: "./[name].[chunkhash:8].js",
  },
}

   работать отдельноdevиbuildСценарий команды, выходные данные согласуются с одной конфигурацией.

производственный режим

РаноwebpackВ версии слишком много элементов конфигурации, используемых в разных средах, которые нельзя использовать из коробки.webpack4добавлено вmodeЭлемент конфигурации, с помощью которого можно переключать режим упаковки.

   В настоящее время в производственной среде находится следующее:webpackЭлементы конфигурации, подходящие для производственных сред, добавляются автоматически.

// webpack.config.js
module.exports = {
  ...
  mode: "production"
}

переменная среды

существуетwebpackможно использовать вDefinePluginДобавьте разные переменные среды для производственной среды и среды разработки, т.е.webpack.DefinePluginиспользуется для установки глобальных переменных в среде браузера (не будет монтироваться вwindowначальство).

  webpack.DefinePluginПрименяется ко всем модулям и полностью заменяет переменные среды в модуле установленными значениями.

  Корневой каталогwebpack.config.js,package.jsonиsrc,srcвключить нижеmain.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3"
  }
}

// webpack.config.js
const webpack = require('webpack')

module.exports = {
  entry: './src/main.js',
  output: {
    filename: "./[name].js",
  },
  plugins: [
    new webpack.DefinePlugin({
      ENV: JSON.stringify('production'),
    })
  ],
  mode: 'development',
  devtool: 'none',
}

// src/main.js
console.log(ENV)

   Проверьте выходной каталог после упаковкиdistсерединаmain.jsфайл, которыйENVполностью заменяется"production".

// dist/main.js
 "./src/main.js":(function(module, exports) {
    console.log("production")
})

   Обратите внимание, что для строк или объектов, содержащих строки, добавьтеJSON.stringify, если не добавленоJSON.stringify, после подстановки станет имя переменной, а не строковое значение, то есть указанное вышеENVбудет заменен наproduction(без строковых кавычек).

   В дополнение к значениям строкового типа также могут быть установлены другие типы переменных среды.

new webpack.DefinePlugin({
  ENV: JSON.stringify("production"),
  ENVIR: '"development"',
  IS_PRODUCTION: true,
  ENV_ID: 1038,
  CONSTANTS: JSON.stringify({
    TYPES: ["foo", "bar"],
  }),
})

   Многие фреймворки и библиотеки используютprocess.env.NODE_ENVКак переменная, которая отличает среду разработки от производственной среды, ее значение равноproductionТо есть текущая среда является производственной средой, и код среды разработки, такой как информация о предупреждениях и журналы, будет удален при упаковке библиотеки и фреймворка, что поможет уменьшить размер кода и улучшить работу. скорость.

   можно настроить следующим образомprocess.env.NODE_ENVпеременная, обратите внимание, что если она включенаmode: 'production',ноwebapckбудет установлено автоматическиprocess.env.NODE_ENVзначение, нет необходимости устанавливать его снова.

new webpack.DefinePlugin({
  "process.env.NODE_ENV": JSON.stringify("development"),
})

Дифференцировать путь окружающей среды

scripts

  webpack4введение версииmodeсвойства, в том числеdevelopment,production,noneТри режима.

  developmentрежим поместит модуль внутрьprocess.env.NODE_ENVЗначение установлено наdevelopment, позволяя среде разработкиwebpackплагин.productionрежим поместит модуль внутрьprocess.env.NODE_ENVЗначение установлено наproduction, позволяя производитьwebpackплагин.

Доступны наwebpack.config.jsустановить вmode, также доступный вpackage.jsonсерединаscriptsустановить в команде скрипта--mode.

// package.json
"scripts": {
    "build-dev": "webpack --mode=development",
    "build-prod": "webpack --mode=production"
}

  Также по умолчанию установлены специальные скриптыmode,следующее"dev": "webpack-dev-server"изmodeзаdevelopment,"build": "webpack"изmodeзаproduction.

// package.json
"scripts": {
    "dev": "webpack-dev-server",
    "build": "webpack"
}

   А внутри модуля можноprocess.env.NODE_ENVЗначение оценки текущей среды, обратите внимание наmodeСпособ заключается в том, что его можно передать в любом модуле с помощьюprocess.env.NODE_ENVПолучить текущие переменные среды, но не можетnodeокрестности(webpackфайл конфигурации), чтобы получить текущие переменные среды.

// package.json
"scripts": {
    "build": "webpack"
}

// src/mian.js
console.log(process.env.NODE_ENV) // production

// webpack.config.js
console.log(process.env.NODE_ENV) // undefined

module.exports = {
  entry: "./src/main.js",
  ...
}

следующееwebpack.config.jsВы можете получить переменные среды через функции, но вы не можете получить переменные среды вне функций.main.jsСредняя выходная мощностьproductionиз-за специального скрипта"build": "webpack"будет установлено по умолчаниюmodeзаproductionмодель.

// package.json
"scripts": {
    "build-dev": "webpack --env=development",
    "build-prod": "webpack --env=production"
}

// webpack.config.js
console.log(process.env.NODE_ENV) // undefined

module.exports = (env) => {
  console.log(env) // development | production

  return {
    entry: "./src/main.js",
    ...
  }
}

// src/main.js
console.log(process.env.NODE_ENV) // production

webpack.DefinePlugin

  scriptsпуть внутри модуляprocess.env.NODE_ENVТолько несколько фиксированных значений.

  webpack.DefinePluginЗатем вы можете установить модульprocess.env.NODE_ENVлюбое значение, но оно не может бытьnodeПолучите текущие переменные среды в файле environment.

// package.json
"scripts": {
  "build": "webpack"
}

// webpack.config.js
const webpack = require("webpack")

console.log(process.env.NODE_ENV) // undefined

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  plugins: [
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify('dev'),
    })
  ]
}

// src/main.js
console.log(process.env.NODE_ENV) // dev

cross-env

   Ни один из двух вышеперечисленных методовnodeокрестности(webpakфайл конфигурации) для получения переменных окружения,scriptsМетод может быть получен только внутри функции через метод функции и не может быть получен в функции.webpack.config.jsчтобы получить текущие переменные среды.

   С помощью сторонних плагиновcross-envдопустимыйnodeСреда получает текущую переменную среды и может произвольно устанавливать значение переменной среды.

// package.json
"scripts": {
    "build": "cross-env ENVIR=prod webpack"
},
"devDependencies": {
    "cross-env": "^7.0.3",
    ...
}

// webpack.config.js
console.log(process.env.ENVIR) // prod

module.exports = {
  entry: "./src/main.js",
  ...
}

// src/main.js
console.log(process.env.ENVIR) // undefined

source map

  source mapОтносится к процессу преобразования скомпилированного, сжатого и упакованного кода обратно в исходный код.webpackУпакованный и сжатый код практически не читается, в это время код выдает ошибку, и очень сложно отследить его стек вызовов.

Конфигурация не включена

  Корневой каталог включаетpackage.json,webpack.config.jsиsrcпапка,srcвключить нижеindex.html,main.jsиstyle.scssMiniCssExtractPluginОсновная функция плагина заключается в извлеченииcssфайл стиля.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "css-loader": "^0.28.9",
    "html-webpack-plugin": "^3.2.0",
    "node-sass": "^4.7.2",
    "sass-loader": "^6.0.7",
    "mini-css-extract-plugin": "^0.5.0",
    "style-loader": "^0.19.0",
    "webpack": "4.29.4",
    "webpack-cli": "^3.2.3"
  }
}

// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")

module.exports = {
  entry: "./src/main.js",
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css",
    }),
  ],
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          'css-loader',
          'sass-loader'
        ],
      }
    ]
  }
}

// src/index.html
<html lang="zh-CN">
  <body>
    <p>hello world</p>
  </body>
</html>

// src/main.js
import './index.scss'

console.log('source-map')

// src/index.scss
$color: red;

p {
  color: $color;
}

воплощать в жизньbuildПосле того, как скрипт упакован, вывод в корневую директориюindex.html,main.css,main.js,использоватьVS CodeПлагин редактораLive Server,index.htmlЩелкните правой кнопкой мыши внутриOpen with Live Server,Проверятьindex.htmlРазвернут на сервере.

   Проверьте вывод в консоли ниже.

在这里插入图片描述

  Нажмитеmian.js:formatted:76Перейти к следующему местоположению, но вы можете только просмотреть расположение этого оператора вывода в упакованном коде и не можете вернуться к исходному коду.

在这里插入图片描述

   Затем просмотрите стили в консоли.

在这里插入图片描述

  Нажмитеmian.css:1Если вы перейдете к следующему местоположению, вы сможете только просмотреть упакованный код стиля, но не сможете вернуться назад.

在这里插入图片描述

включить конфигурацию

существуетwebpack.config.jsдобавлено вdevtoolвключиjsдокументsource map, а дляscss,cssвам нужно добавить доп.source mapэлемент конфигурации.

// webpack.config.js
module.exports = {
  ...
  module: {
    rules: [
      {
        test: /\.scss$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader,
          },
          {
            loader: 'css-loader',
            options: {
              sourceMap: true
            }
          },
          {
            loader: 'sass-loader',
            options: {
              sourceMap: true
            }
          }
        ]
      }
    ]
  },
  devtool: 'source-map'
}

   выполнить сноваbuildупаковка скрипта,distВ каталоге будет еще несколькоmapфайл, так как включенdevtoolэлемент конфигурации,source mapОн будет проходиться шаг за шагом с исходным кодом до окончательногоmapфайл, имя файла которого по умолчанию соответствует выходному файлу плюс.mapсуффикс, напримерmain.js.map,main.jsВ конце по умолчанию будет добавлен комментарий для идентификацииmapРасположение файла.

// main.js
...
//# sourceMappingURL=main.js.map

   Еще раз проверьте результат вывода на консоли, и вы уже можете увидеть конкретный номер строки этого оператора в исходном коде.

在这里插入图片描述

  Нажмитеmain.js:2Перейти к следующему, вы можете увидеть конкретную ситуацию этого заявления.

在这里插入图片描述

Стиль    можно полностью проследить доscssв файле.

在这里插入图片描述

  Нажмитеindex.scss:3Перейти к ниже.

在这里插入图片描述

Показатели безопасности

Наsource mapПосле этого в инструментах разработчикаwebpack://Исходный код проанализированного проекта можно найти в каталоге.

   Обратите внимание, что при открытии инструментов разработчика браузераmapФайлы загружаются одновременно, а затем браузер использует их для анализа соответствующего выходного файла, анализируя структуру каталогов и содержимое исходного кода.

  mapФайл, как правило, большой и не будет загружен без открытия инструментов разработчика, а с помощьюsource mapБудут определенные риски безопасности.

  webpackпри условииhidden-source-mapиnosources-source-mapДве стратегии улучшенияsource mapбезопасность.

  hidden-source-mapвсе равно будет генерировать полныйmapфайл, но пара не добавляется в выходной файлmapссылка на файл. Чтобы отследить исходный код, вы можете использовать сторонние сервисы (такие какSentry),будетmapфайл загружен.

  nosources-source-mapСтруктуру каталогов исходного кода можно просмотреть в инструментах разработчика, но конкретное содержимое файла будет скрыто. можно посмотреть в консолиconsoleТочное количество строк в логе, которого в принципе достаточно для возврата ошибок.

在这里插入图片描述

элемент конфигурации devtool

  devtoolИспользуется для отладки, включая более десятка следующих конфигураций.

  • none
  • eval
  • eval-source-map
  • cheap-eval-source-map
  • cheap-module-eval-source-map
  • source-map
  • cheap-source-map
  • cheap-module-source-map
  • inline-source-map
  • inline-cheap-source-map
  • inline-cheap-module-source-map
  • hidden-source-map
  • nosources-source-map

который включаетeval,cheap,module,source-mapи другие ключевые слова, большинство из которых объединены, и их конкретные характеристики заключаются в следующем.

  • eval:использоватьevalобертывает код модуля и существуетsourceURL,sourceURLуказать исходный файл
  • cheap: Бэйлmapфайл, информация о позиции столбца исходного кода не сохраняется, включается только информация о позиции строки. пренебрегатьloaderизsource map, и показывать только транспилированный код
  • module:включаютloaderизsourcemap
  • source-map:генерировать.mapдокумент

none

  Корневой каталог включаетpackage.json,webpack.config.jsиsrcпапка,srcвключить нижеindex.htmlиmain.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "html-webpack-plugin": "^3.2.0",
    "webpack": "4.29.4",
    "webpack-cli": "^3.2.3"
  }
}

// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
  entry: "./src/main.js",
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html",
    }),
  ],
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          cacheDirectory: true,
          presets: [["@babel/preset-env", { modules: false }]],
        },
      },
    ],
  },
  devtool: "none",
  mode: "development"
}

// src/index.html
<html lang="zh-CN">
  <body>
    <p>hello world</p>
  </body>
</html>

// src/main.js
const fn = ()=>{
    console.log('source map')
}

fn()

бегатьbuildПосле команды скрипта просмотрите вывод в консоли.

在这里插入图片描述

  Нажмитеmian.js:97Прыгайте ниже.

在这里插入图片描述

  noneЭлемент конфигурации нельзя отследить до исходного кода, он основан только на конфигурации.loaderКод модуля транспилируется.

eval

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьeval, затем запуститеbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  evalВ элементе конфигурации упакован код модуляevalпакет, в том числеsourceURL, исходный код трассировкиloaderПреобразовано (функция стрелки преобразована в обычную функцию), с информацией о столбце курсора.

source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьsource-map, беги сноваbuildкоманды скрипта,distВ каталоге создано много.mapдокумент.

在这里插入图片描述

   Просмотр кода упакованного вывода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  source-mapВ элементе конфигурации, сгенерированном.mapфайл, код вывода пакета добавляется в концеsourceMappingURL, исходный код трассировки — это исходный код с информацией о столбце курсора.

cheap-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьcheap-source-map,бегатьbuildкоманды сценария, а также вdistсоздается в каталоге.mapфайлы, упакованный выходной код иsource-mapПоследовательный.

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  cheap-source-mapВ элементе конфигурации он также будет генерировать.mapфайл, конец упакованного выходного кода также будет добавленsourceMappingURL, исходный код трассировкиloaderПреобразованные (стрелочные функции преобразуются в обычные функции), без информации о столбце курсора (курсор находится в начале строки).

eval-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьeval-source-map,бегатьbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  eval-source-mapВ элементе конфигурации упакован код модуляevalпакет, в том числеsourceURLиsourceMappingURL, не будет генерироваться.mapфайл, но будетmapПреобразование содержимого файла вbase64кодировка вставлена ​​вsourceMappingURLПозже исходный код трассировки представляет собой исходный код с информацией о столбце курсора.

cheap-eval-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьcheap-eval-source-map,бегатьbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  cheap-eval-source-mapВ элементе конфигурации упакован код модуляevalпакет, в том числеsourceURLиsourceMappingURL, не будет генерироваться.mapфайл, но будетmapПреобразование содержимого файла вbase64кодировка вставлена ​​вsourceMappingURLПозже исходный код трассировкиloaderПреобразованные (стрелочные функции преобразуются в обычные функции), без информации о столбце курсора (курсор находится в начале строки).

cheap-module-eval-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьcheap-module-eval-source-map,бегатьbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  cheap-module-eval-source-mapВ элементе конфигурации упакован код модуляevalпакет, в том числеsourceURLиsourceMappingURL, не будет генерироваться.mapфайл, но будетmapПреобразование содержимого файла вbase64кодировка вставлена ​​вsourceMappingURLПозже исходный код трассировки представляет собой исходный код без информации о столбце курсора (курсор находится в начале строки).

cheap-module-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьcheap-module-source-map,бегатьbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  cheap-module-source-mapВ элементе конфигурации он также будет генерировать.mapфайл, конец упакованного выходного кода также будет добавленsourceMappingURL, исходный код трассировки является исходным кодом, без информации о столбце курсора (курсор находится в начале строки).

inline-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьinline-source-map,бегатьbuildКоманда сценария для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  inline-source-mapВ элементе конфигурации он не будет сгенерирован.mapфайл, но будетmapПреобразование содержимого файла вbase64кодировка вставлена ​​вsourceMappingURLПозже исходный код трассировки представляет собой исходный код с информацией о столбце курсора.

hidden-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьhidden-source-map,бегатьbuildкоманды сценария, а также вdistсоздается в каталоге.mapфайл для просмотра упакованного и выводимого кода.

在这里插入图片描述

   Консоль Нажмите и прыгайте после просмотра вывода.

在这里插入图片描述

  inline-source-mapВ элементе конфигурации он будет генерировать.mapфайл, но не сохранитmapСсылки на файлы (нетsourceMappingURL) и не может быть отслежен до исходного кода.

nosources-source-map

Исправлятьwebpack.config.jsсерединаdevtoolсобственностьnosources-source-map,бегатьbuildПосле команды скрипта просмотрите вывод в консоли.

在这里插入图片描述

  Нажмитеmain.js:2Прыгайте ниже.

在这里插入图片描述

   Просмотр кода упакованного вывода.

在这里插入图片描述

  nosources-source-mapВ элементе конфигурации, сгенерированном.mapфайл, код вывода пакета добавляется в концеsourceMappingURL, исходный код невозможно отследить (структуру каталогов исходного кода можно просмотреть, а конкретное содержимое скрыто), но его можно просмотреть в консолиconsoleТочное количество строк журнала.

Сравнение различий

   Ниже приведены отличия каждого элемента конфигурации, среди которых скорость сборкиfastest > fast > ok > slow > slowest.

devtool скорость наращивания метод карты оценочный пакет sourceMappingURL Есть ли информация о столбце курсора Это имеет обратную силу код возврата
none fastest - - - - нет -
eval fast evalвнутри функцииsourceURLПуть к исходному файлу ссылки да - имеют да loaderтранспилированный код
source-map slowest Добавить в конце модуляsourceMappingURLЦитироватьmap нет Ссылка на сайтmapимя файла имеют да исходный код
cheap-source-map ok Добавить в конце модуляsourceMappingURLЦитироватьmap нет Ссылка на сайтmapимя файла нет да loaderтранспилированный код
eval-source-map slowest evalвнутри функцииsourceURLОбратитесь к пути к исходному файлу и вставьте его в конец функции.sourceMappingURL да mapсодержаниеbase64кодирование да да исходный код
cheap-eval-source-map ok evalвнутри функцииsourceURLОбратитесь к пути к исходному файлу и вставьте его в конец функции.sourceMappingURL да mapсодержаниеbase64кодирование нет да loaderтранспилированный код
cheap-module-eval-source-map slow evalsourceURL в функции ссылается на путь к исходному файлу, а затем вставляется в конец функцииsourceMappingURL да mapсодержаниеbase64кодирование нет да исходный код
cheap-module-source-map slow Добавить в конце модуляsourceMappingURLЦитироватьmap нет Ссылка на сайтmapимя файла нет да исходный код
inline-source-map slowest Добавить в конце модуляsourceMappingURL нет mapсодержаниеbase64кодирование да да исходный код
hidden-source-map slowest - нет - - - -
nosources-source-map slowest Добавить в конце модуляsourceMappingURLЦитироватьmap нет Ссылка на сайтmapимя файла - - -

сжатие ресурсов

Как правило, ресурсы, опубликованные в онлайн-среде, подвергаются сжатию кода (сокращению), то есть удалению избыточных пробелов, новых строк и невыполненного кода, сокращению имен переменных, удалению комментариев и т. д., при этом гарантируется неизменность результата выполнения. с более короткой формой.

  Общий размер кода будет значительно уменьшен после сжатия, и в то же время он будет в основном нечитаемым, что в определенной степени повышает безопасность кода.

Сократить JavaScript

  webpack3и ниже можно пройтиwebpack.optimize.UglifyJsPluginРеализовать сжатие кода.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^3.10.0"
  }
}

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./dist/[name].js"
  },
  plugins: [new webpack.optimize.UglifyJsPlugin()]
}

// src/main.js
const fn = function () {
  console.log("hello world")
}

fn()

  webpack4Затем используйте по умолчаниюterser-webpack-pluginКак встроенный плагин сжатия, он поддерживаетES6+Сжатие кода. существуетwebpack4пройти вoptimization.minimizeОпределяет, включать ли сжатие.По умолчанию оно отключено в среде разработки и включено по умолчанию в производственной среде.

// webpack.config.js
module.exports = {
    ...
    optimization: {
        minimize: true
    }
}

   также можно сделать черезoptimization.minimizerПользовательские плагины сжатия и элементы их конфигурации, которые могут быть автоматически удалены при упаковке следующим образом.console.log.

// webpack.config.js
const TerserPlugin = require("terser-webpack-plugin")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  optimization: {
    minimize: true,
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          compress: {
            pure_funcs: ["console.log"],
          },
        },
      }),
    ],
  },
}

Сжать CSS

  СжатиеcssПервый заключается в использованииextract-text-webpack-pluginилиmini-css-extract-pluginИзвлеките стиль, затем используйтеoptimize-css-assets-webpack-pluginсжимать.

  Корневой каталогpackage.json,webpack.config.jsиsrcпапка,srcвключить нижеmain.jsиindex.css.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "css-loader": "^0.28.7",
    "mini-css-extract-plugin": "^0.5.0",
    "optimize-css-assets-webpack-plugin": "^4.0.1",
    "webpack": "4.29.4",
    "webpack-cli": "^3.2.3"
  }
}

// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: [
          {
            loader: MiniCssExtractPlugin.loader
          },
          "css-loader"
        ]
      }
    ]
  },
  plugins: [
    new MiniCssExtractPlugin({
      filename: "[name].css",
      chunkFilename: "[id].css"
    }),
  ],
  optimization: {
    minimize: true,
    minimizer: [new OptimizeCSSAssetsPlugin()]
  },
}

// src/main.js
import "./index.css"

console.log("hello world")

// src/index.css
p {
  color: red;
}

воплощать в жизньbuildПосле того, как скрипт упакован, просмотрите выводcssдокумент.

// dist/main.css
p {
  color: red;
}

тайник

  Кэш относится к повторному использованию ресурсов, уже полученных браузером.Подробная политика кэширования (например, время кэширования) определяется сервером, и браузер будет использовать локальный кэш для ответа до истечения срока действия ресурса.

   Но и этот метод принесет проблемы, если кодbug fix, и хотите обновить сразу во всех браузерах пользователей, лучше всего изменить ресурсURL, вынуждая клиента повторно скачать ресурс.

  Общим методом является вычисление содержимого ресурса один раз при каждой его упаковке.hash, и сохраняется в имени файла как номер версии.

номер версии

   обычно используется следующим образомchunkhashв качестве номера версии файла, который будет использоваться отдельно для каждогоchunkрассчитатьhashценность.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "4.29.4",
    "webpack-cli": "^3.2.3"
  }
}

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name]@[chunkhash:8].js"
  }
}

// src/main.js
console.log("hello world")

бегатьbuildСкрипт упакован следующим образом.

在这里插入图片描述

   Изменение имени файла ресурсов также означает, чтоHTMLИзменения в эталонном пути могут быть сделаны с помощьюhtml-webpack-pluginПлагин, который автоматически синхронизирует имена ресурсов, на которые ссылаются, после упаковки.

// package.json
"devDependencies": {
    ...
    "html-webpack-plugin": "3.2.0"
}

// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")

module.exports = {
  ...
  plugins: [
    new HtmlWebpackPlugin({
      template: "./src/index.html"
    })
  ]
}


// src/html
<html lang="zh-CN">
  <body>
    <p>hello world</p>
  </body>
</html>

   снова бежатьbuildПакет скриптов, открытьdistВнизindex.html, где пути к ресурсам, на которые есть ссылки, синхронизируются.

在这里插入图片描述

CommonsChunkPlugin

пройти черезCommonsChunkPluginНекоторые редко изменяемые коды могут извлекаться отдельно, чтобы отличить их от часто повторяющихся бизнес-кодов.Эти ресурсы могут постоянно кэшироваться на стороне клиента.

ноwebpack3и следующее указано для каждого модуляidОн увеличивается на число, и когда вставляется новый модуль, это вызывает другие модули.idизменение, которое влияетchunkсодержание в финальном воздействииchunkhashзначение, что приводит к повторной загрузке ресурсов, которые не нужно загружать.

  Корневой каталогpackage.json,webpack.config.jsиsrcпапка,srcвключить нижеmain.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "webpack": "^3.10.0"
  },
  "dependencies": {
    "jquery": "^3.2.1"
  }
}

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    main: "./src/main.js",
    vendor: ["jquery"]
  },
  output: {
    filename: "./dist/[name]@[chunkhash:8].js"
  },
  plugins: [
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name]@[chunkhash:8].js"
    })
  ]
}

// src/main.js
import "jquery"

console.log("main.js")

бегатьbuildСкрипт упаковки, просмотр выходных ресурсов, которыеvendorСодержит только сторонние модулиjqueryиwebpackфайл времени выполнения.

在这里插入图片描述

затем вsrcпод новымutils.js,main.jsвведено в.

// src/main.js
import "jquery"
import "./utils"

console.log("main.js")

// src/utils.js
console.log("utils.js")

   выполнить сноваbuildСкрипт упаковки, просмотр выходных ресурсов.

在这里插入图片描述

   Это создает проблему,vendorМодули не изменились, но изменились их путевые имена.

В сравненииdistПод содержаниемvendor@5eb95a94.jsиvendor@fe14193b.js, произошли только следующие два изменения.

在这里插入图片描述

在这里插入图片描述

HashedModuleIdsPlugin

   Решение — сменить модульidметод генерации,webpack3ВстроенныйHashedModuleIdsPluginПлагин, он может генерировать строковый тип для каждого модуля в соответствии с его путемhash id.

// src/main.js
import "jquery"

console.log("main.js")

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: {
    main: "./src/main.js",
    vendor: ["jquery"],
  },
  output: {
    filename: "./dist/[name]@[chunkhash:8].js",
  },
  plugins: [
    new webpack.HashedModuleIdsPlugin(),
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name]@[chunkhash:8].js",
    }),
  ],
}

бегатьbuildСкрипт упаковки, просмотр выходных ресурсов.

在这里插入图片描述

  main.jsвводитьutils.js.

import "jquery"
import "./utils"

console.log("main.js")

   снова бежатьbuildБэйл.

在这里插入图片描述

так какvendorВключать только сторонние модулиjqueryиwebpackвремя выполнения, покаjqueryПуть всегда фиксирован, поэтому егоhash idвсегда фиксируется.

  webpack3Следующая версия, потому что она не поддерживает строковый типid,можно использоватьwebpack-hashed-module-id-pluginплагин. иwebpack4+Модифицировал модульidметод генерации, больше нет этой проблемы.

Анализ мониторинга

   Вы можете использовать сторонние плагины для упаковки выводаbundleТома отслеживаются и анализируются, чтобы предотвратить добавление ненужных избыточных модулей.

Import Cost

  Vs CodeсерединаImport CostРазмер импортированного модуля можно определить в режиме реального времени, когда в коде есть ссылка на новый модуль (в основномnode_modulesмодуль в ), он рассчитает сжатый иgzipзанимаемый объем после.

在这里插入图片描述

webpack-bundle-analyzer

   Еще одним инструментом визуального анализа являетсяwebpack-bundle-analyzer, может анализироватьbundleсочинение.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "vue": "^2.6.12",
    "vue-router": "^3.5.1",
    "vuex": "^3.6.2",
    "webpack": "^3.10.0",
    "webpack-bundle-analyzer": "^4.4.1"
  }
}

// webpack.config.js
const webpack = require("webpack")
const Analyzer = require("webpack-bundle-analyzer").BundleAnalyzerPlugin

module.exports = {
  entry: {
    main: "./src/main.js",
    vendor: ["vue", "vuex", "vue-router"]
  },
  output: {
    filename: "./dist/[name].js"
  },
  plugins: [
    new Analyzer(),
    new webpack.optimize.CommonsChunkPlugin({
      name: "vendor",
      filename: "./dist/[name].js"
    })
  ]
}

// src/main.js
import Vue from "vue"
import Vuex from "vuex"
import VueRouter from "vue-router"
import { log } from "./utils.js"

console.log(Vue, Vuex, VueRouter, log, "main.js")

// src/utils.js
export function log() {
  console.log("utils.js")
}

бегатьbuildРезультаты анализа сценария следующие.

在这里插入图片描述

Оптимизация упаковки

   Если вы не видите никаких точек оптимизации на ранней стадии проекта и вносите их в проект, это увеличит сложность, и эффект оптимизации будет неидеальным. Как правило, проект развивается до определенного масштаба, и проблемы с производительностью возникают до конкретной оптимизации.

HappyPack

  HappyPackэто многопоточность для улучшенияwebpackПлагин для скорости упаковки.

   Трудоемкая часть процесса упаковкиloaderПереводите различные ресурсы, такие какbabelперевестиES6+и так далее, конкретный рабочий процесс выглядит следующим образом.

  1. Получить запись об упаковке из конфигурации
  2. совпадениеloaderправила и транспилирует входной модуль
  3. Поиск зависимостей для транспилированных модулей
  4. Повторите шаги для вновь найденных модулей.2и шаги3, пока не останется новых зависимых модулей

   Шаги2шагать4это рекурсивный процесс,webpackНеобходимо шаг за шагом приобретать ресурсы более глубокого уровня, а затем переводить их один за другим. Фундаментальная проблема заключается вwebpackоднопоточный, если модуль зависит от нескольких других модулей,webpackЭти модули должны быть переведены один за другим. Хотя эти задачи перевода не зависят друг от друга, они должны выполняться последовательно. иHappyPackОсновная функция заключается в том, что он может открывать несколько потоков, параллельно переводить разные модули и в полной мере использовать локальные ресурсы для повышения скорости упаковки.

одиночный погрузчик

   Использовать при использованииHappyPackкоторый предоставилloaderзаменить оригиналloader, и конвертировать исходныйloaderперейти кHappyPackплагин.

  Корневой каталогpackage.json,webpack.config.jsиsrcsrcвключить нижеmain.js,bar.js,foo.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "vue": "^2.6.12",
    "vuex": "^3.6.2",
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3",
    "happypack": "^5.0.0"
  }
}

// src/main.js
import "./foo.js"
import "./bar.js"

console.log("main.js")

// src/foo.js
import vue from "vue"

console.log(vue, "foo.js")

// src/bar.js
import Vuex from "vuex"

console.log(Vuex, "bar.js")

ИсходныйwebpackКонфигурация следующая.

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          cacheDirectory: true,
          presets: [["@babel/preset-env", { modules: false }]],
        },
      },
    ],
  },
}

  ВведеноHappyPackМодификация после плагинаwebpackконфигурация.

// webpack.config.js
const HappyPack = require("happypack")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        exclude: /node_modules/,
        loader: "happypack/loader",
      },
    ],
  },
  plugins: [
    new HappyPack({
      loaders: [
        {
          loader: "babel-loader",
          options: {
            cacheDirectory: true,
            presets: [["@babel/preset-env", { modules: false }]],
          },
        },
      ],
    }),
  ],
}

несколько загрузчиков

  HappyPackоптимизировать несколькоloader, требуется для каждогоloaderнастроитьid,в противном случаеHappyPackне могу знатьrulesиpluginsКак переписываться по одному.

  Корневой каталогpackage.json,webpack.config.jsиsrc,srcвключить нижеmain.jsиindex.css.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "@babel/core": "^7.2.2",
    "@babel/preset-env": "^7.3.1",
    "babel-loader": "^8.0.5",
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3",
    "happypack": "^5.0.0",
    "css-loader": "^0.28.9",
    "style-loader": "^0.19.0"
  }
}

// src/main.js
import "./index.css"

console.log("main.js")

// src/index.css
p {
  color: red;
}

ИсходныйwebpackКонфигурация следующая.

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "babel-loader",
        exclude: /node_modules/,
        options: {
          cacheDirectory: true,
          presets: [["@babel/preset-env", { modules: false }]],
        },
      },
      {
        test: /\.css$/,
        use: ["style-loader", "css-loader"],
      },
    ],
  },
}

  ВведеноHappyPackМодификация после плагинаwebpackконфигурация.

// webpack.config.js
const HappyPack = require("happypack")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  module: {
    rules: [
      {
        test: /\.js$/,
        loader: "happypack/loader?id=js",
        exclude: /node_modules/,
      },
      {
        test: /\.css$/,
        loader: "happypack/loader?id=css",
      },
    ],
  },
  plugins: [
    new HappyPack({
      id: "js",
      loaders: [
        {
          loader: "babel-loader",
          options: {
            cacheDirectory: true,
            presets: [["@babel/preset-env", { modules: false }]],
          },
        },
      ],
    }),
    new HappyPack({
      id: "css",
      loaders: ["style-loader", "css-loader"],
    }),
  ],
}

Сузить пакет

   Как правило, есть два способа повысить производительность: увеличить ресурсы или уменьшить масштаб. Увеличение ресурсов означает использование большегоCPUи памяти, используя больше вычислительной мощности, чтобы сократить время выполнения задач. Сужение касается самой задачи, такой как удаление избыточных процессов или отказ от повторяющейся работы.

exclude/include

Заjsмодуль, в общемnode_modulesкаталог исключен.

noParse

   Некоторые сторонние библиотеки совершенно нежелательныwebpackдля разбора, т.е. не желают применять какие-либоloaderrules, внутри библиотеки не будет зависимостей от других модулей, и вы можете использовать ее в это время.noParseИгнорируй это.

   Следующее означает игнорировать все имена файлов, включаяlodashмодули, эти модули по-прежнему будут упакованы в ресурсы, ноwebpackОн не будет разобран никоим образом.

// webpack.config.js
module.exports = {
  ...
  module: {
    noParse: /lodash/
}

IgnorePlugin

  IgnorePluginПлагины могут полностью исключать некоторые модули, и исключенные модули не будут упакованы в файлы ресурсов, даже если на них есть ссылки.

следующееmoment.jsЭто библиотека обработки времени.Для локализации она загружает много языковых пакетов.Вообще говоря, она не используется и займет много места.Его можно использоватьIgnorePluginИгнорируй это.

  Корневой каталог включаетpackage.json,webpack.config.js,src,srcвключить нижеmain.js.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "moment": "^2.29.1",
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3"
  }
}

// webpack.config.js
module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  }
}

// src/main.js
import "moment"

console.log("main.js")

бегатьbuildСкрипт упаковки, просмотр выходных ресурсов.

在这里插入图片描述

Исправлятьwebpack.config.jsresourceRegExpсоответствующие файлы ресурсов,contextRegExpСоответствие каталогу поиска.

// webpack.config.js
const webpack = require("webpack")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  plugins: [
    new webpack.IgnorePlugin({
      resourceRegExp: /^\.\/locale$/,
      contextRegExp: /moment$/,
    }),
  ],
}

   снова бежатьbuildСкрипт упаковки, просмотр выходных ресурсов.

在这里插入图片描述

DllPlugin

РаноwindowsМетод оптимизации памяти, называемый динамической библиотекой, возникает из-за того, что система ограничена проблемой небольшого объема памяти компьютера.Когда одна и та же подпрограмма вызывается несколькими программами, чтобы уменьшить потребление памяти, эта подпрограмма может храниться как исполняемый файл, который генерирует и использует один и тот же экземпляр в памяти только при вызове несколькими программами.

  DllPluginОпираясь на эту идею, для сторонних модулей или некоторых модулей, которые изменяются нечасто, их можно предварительно скомпилировать и упаковать, а затем напрямую использовать в фактическом процессе построения проекта. При предварительной упаковке будет дополнительно формироваться список модулей, и этот список будет играть роль связывания и индексации при упаковке инженерных бизнес-модулей.

  DllPluginиCode SplittingТочно так же оба могут использоваться для извлечения общих модулей, но есть и существенные различия.Code SplittingЭто установка определенных правил и извлечение модулей в соответствии с правилами в процессе упаковки.DllPluginбудетvendorПолностью разделен, имеет свой собственный наборwebpackОн настраивается и упаковывается независимо, и он больше не будет обрабатываться при создании фактического проекта, и его можно будет использовать напрямую. теоретическиDllPluginбыло бы лучше, чемCode SplittingСкорость упаковки выше, но это также соответственно увеличивает сложность настройки и управления ресурсами. можно понимать какDllPluginТеоретически быстрее заменить один пакет двумя пакетами, первый пакет для редко меняющихся модулей, а второй пакет для бизнес-модулей.

dll упаковка

  Корневой каталог включаетwebpack.config.js,package.jsonиsrc,srcвключить нижеmain.js,index.html.

// package.json
{
  ...
  "scripts": {
    "build": "webpack"
  },
  "devDependencies": {
    "vue": "^2.6.12",
    "webpack": "4.29.4",
    "webpack-cli": "3.2.3"
  }
}

// src/main.js
import "vue"

console.log("main.js")

   Сначала создайте отдельный для динамической библиотеки.webpackконфигурационный файл, назовите егоwebpack.dll.config.js. вoutput.filenameимя динамической библиотеки,output.pathвыходной путь библиотеки динамической компоновки,output.libraryдолжен иDllPluginсерединаnameПоследовательный.DllPluginсерединаpathвыходной путь манифеста модуля библиотеки динамической компоновки,pathзаmanifest.jsonв файлеnameзначение поля.

// webpack.dll.config.js
const path = require("path")
const webpack = require("webpack")

const dllAssetPath = path.join(__dirname, "dist", "dll")
const dllLibraryName = "dll"

module.exports = {
  entry: ["vue"],
  output: {
    path: dllAssetPath,
    filename: "dll.js",
    library: dllLibraryName,
  },
  plugins: [
    new webpack.DllPlugin({
      name: dllLibraryName,
      path: path.join(dllAssetPath, "manifest.json"),
    }),
  ],
}

   затем настроитьpackage.json, добавьте команду скрипта.

// package.json
{
    ...
    "scripts": {
        "dll": "webpack --config webpack.dll.config.js"
    }
}

бегатьdllкоманда скрипта, будет вdistПод содержаниемdllсоздается в папкеdll.jsиmanifest.json. вdll.jsИмя переменной в приведенной выше конфигурацииoutput.library,manifest.jsonсерединаnameвышеDllPluginсерединаname.

// dist/dll/dll.js
var dll = (function (params) {
    ...
})(...)

// dist/dll/manifest.json
{
  "name": "dll",
  "content": {
      ...
  }
}

   Наконец, вам нужно сделать ссылку в бизнес-кодеdll.js.

// webpack.config.js
const path = require("path")
const webpack = require("webpack")

module.exports = {
  entry: "./src/main.js",
  output: {
    filename: "./[name].js",
  },
  plugins: [
    new webpack.DllReferencePlugin({
      manifest: require(path.join(__dirname, "dist/dll/manifest.json")),
    }),
  ],
}

   введение страницыscriptТаким образом, страница выполняется дляdll.jsглобальные переменные объявляются, когдаdllmanifestЭквивалент инъекцииmain.jsкарта ресурсов,main.jsпройдет первымnameИмя найденного поляdllизlibrary, так что вwebpack.dll.config.jsсерединаoutput.libraryдолжен иDllPluginсерединаnameПоследовательный.

// src/index.html
<html lang="zh-CN">
  <body>
    <p>hello world</p>
    <script src="./dll/dll.js"></script>
    <script src="./main.js"></script>
  </body>
</html>

проблема с идентификатором

Проверятьmanifest.json, где каждый модуль имеетid, значения которого расположены в порядке возрастания номеров,main.jsкод ссылаетсяdll.jsтакже ссылайтесь на номера, когда модули вid.

  Может существовать после упаковки проектаdll.js(пройти черезDllPluginПостроить),utils.js@[chunkhash].js,main.js. вdll.jsсодержитvue,Тотidза5. При попытке добавить дополнительные модули вdll.jsСреднее время, после восстановленияvueизidстать6.

так какutilsтакже цитируетсяvueмодуль, после восстановления егоchunkhashОн изменится, но его собственное содержимое не изменится, и пользователю клиента останется только заново скачать ресурс.

   Чтобы решить эту проблему, используйтеHashedModuleIdsPluginплагин.

// webpack.dll.config.js
module.exports = {
  plugins: [
    new webpack.DllPlugin({
      ...
    }),
    new webpack.HashedModuleIdsPlugin()
  ]
}

tree shaking

  ES6 ModuleЗависимости создаются во время компиляции кода, а не во время выполнения, на основе этой функции.webpackпри условииtree shakingОн может обнаруживать модули, на которые нет ссылок в проекте в процессе упаковки.Эта часть кода никогда не будет выполнена, поэтому ее также называют «мертвым кодом».

  webpackпометит эту часть кода и удалит их из окончательногоbundleудаленный.

следующееwebpackпри упаковкеbarФункция добавляет флаг, а затем проходит через инструмент минификации для удаления мертвого кода.

// src/main.js
import { foo } from "./utils.js"

foo()

// src/utils.js
export function foo() {
  console.log("foo")
}

export function bar() {
  console.log("bar")
}

Предыдущий

Следующий

🎉 Напишите в конце

🍻Ребята, если вы видели это и считаете, что эта статья была вам полезна, ставьте лайк 👍 илиStar✨Поддержите!

Кодирование вручную, если есть ошибки, исправьте их в комментариях 💬~

Ваша поддержка — самая большая мотивация для меня обновляться💪~

GitHub,Blog,Наггетс,CSDNСинхронизированное обновление, подписывайтесь 😉~