Введение в вебпак
Обзор
webpack
является открытым исходным кодомJavaScript
Инструмент упаковки модулей, основная функция которого заключается в устранении зависимостей между модулями, организации каждого модуля в соответствии с определенными правилами и последовательностями и, наконец, объединении их в один или несколько.JS
файл, весь процесс называется упаковкой модуля.
Модуль — это обработка датыnpm
пакет или пакет, предоставляющий служебные методыJS
документы и т.д. При проектировании структуры программы было бы очень плохо складывать весь код вместе, лучший способ — разбить его на несколько сегментов кода в соответствии с определенной функцией, каждый сегмент кода реализует определенную функцию, и, наконец, он передается через интерфейс комбинация.
JavaScript
В начале проектирования это всего лишь небольшой скриптовый язык, и далеко не факт, что он будет использоваться для реализации сложных сценариев, поэтому модульность лишняя. С развитием техники,HTML
Страницы обычно представляют несколькоscript
файл, но этот подход имеет много недостатков.
Сначала требуется ручное обслуживаниеscript
Порядок загрузки файлов. несколько страницscript
Между ними обычно существуют зависимости, обычно неявные, трудно четко указать, кто от кого зависит, не добавляя комментариев, и проблемы могут легко возникнуть, когда загружено слишком много файлов.
с последующимscript
Все файлы означают однократный запрос статических ресурсов с сервера, а слишком большое количество запросов замедлит скорость рендеринга веб-страницы. и каждыйscript
Область верхнего уровня в теге — это глобальная область, и объявление переменных или функций непосредственно в коде загрязнит глобальную область.
При модульном подходе зависимости между модулями можно четко увидеть с помощью операторов импорта и экспорта. Модули могут быть упакованы с помощью инструментов, и на странице загружаются только объединенные файлы ресурсов, что снижает нагрузку на сеть. И области между несколькими модулями изолированы, и не будет конфликтов имен друг с другом.
Установить
webpack
Методы установки включают глобальную установку и локальную установку.Глобальная установка привязывает переменную среды командной строки, устанавливает ее один раз и запускает везде. Локальная установка добавит его как зависимость проекта, которую можно использовать только внутри проекта.
Если используется глобальная установка, когда над проектом сотрудничают несколько человек, из-заwebpack
Различные версии могут привести к противоречивым результатам вывода. и частично зависят отwebpack
Плагин вызовет внутреннююwebpack
модуль, в этом случае его все равно нужно установить локальноwebpack
.
установить указанную версиюwebpack
,Уведомлениеwebpack4+
версия для установкиwebpack-cli
инструмент командной строки.
npm i webpack@4.29.4 webpack-cli@3.2.3 --save-dev
Можно просмотреть после успешной установкиwebpack
иwebpack-cli
номер версии. Уведомлениеwebpack
Устанавливается локально, поэтому не может использоваться из командной строки.webpack
Инструкции, которые можно использовать только внутри проектаnpx webpack
форма.
npx webpack -v
npx webpack-cli -v
Бэйл
Создать в корневом каталогеindex.html
,index.js
,fn.js
.
// index.html
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<title>Hello World</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
</body>
</html>
// index.js
import fn from './fn.js'
fn()
// fn.js
export default function () {
document.write('Hello World')
}
Консоль запускает следующую команду упаковки, и браузер открываетindex.html
показыватьHello World
. вentry
Ресурсный упакованный вход,webpack
Отсюда запускается поиск зависимости модуля и получается в проектеindex.js
иfn.js
два модуля,output-filename
Для имени выходного ресурса оно появляется после упаковкиdist
Под содержаниемbundle.js
документ,mode
для режима упаковки, в том числеdevelopment
,production
,none
Три режима, среда разработки обычноdevelopment
модель.
работаетnpx webpack -h
Проверятьwebpack
Элементы конфигурации и соответствующие параметры командной строки.
npx webpack --entry=./index.js --output-filename=bundle.js --mode=development
Каждый раз при упаковке необходимо вводить длинную команду, которую можно редактироватьpackage.json
файла, добавив команды скрипта для упрощения набора текста. вscripts
даnpm
Предоставляет функцию команды сценария, которая может напрямую использовать инструкции, добавленные модулем (например,webpack
заменить предыдущийnpx webpack
),бегатьnpm run build
затем открыть сноваindex.html
.
{
...
"scripts": {
"build": "webpack --entry=./index.js --output-filename=bundle.js --mode=development"
}
...
}
Когда проекту требуется все больше и больше конфигураций, в команду нужно добавить больше параметров, которые потом очень сложно поддерживать.webpack
Файл конфигурации по умолчаниюwebpack.config.js
, затем удалитеpackage.json
Параметры упаковки, настроенные в .
// webpack.config.js
module.exports = {
entry: './index.js',
output: {
filename: 'bundle.js'
},
mode: 'development'
}
// package.json
{
...
"scripts": {
"build": "webpack"
}
...
}
Необходимость повторного выполнения при изменении кодаnpm run build
упаковать и открытьindex.html
,webpack
Предоставляет более удобные инструменты разработкиwebpack-dev-serverПовысить эффективность разработки, когда он обнаружит, что исходный файл проекта был обновлен, он автоматически обновится.live-reloading
Браузер, показывающий обновленный контент.
npm i webpack-dev-server@3.1.14 --save-dev
Добавить кdev
скрипт и настройкаwebpack.config.js
.webpack-dev-server
Основная работа заключается в том, чтобы поместить запакованный результат в память, а не писать в файл, каждый разwebpack-dev-server
Когда запрос получен, он просто возвращает упакованный результат в память браузеру. можно удалить поdist
каталог для проверки, даже еслиdist
Каталог не существует, и функция обновления страницы по-прежнему работает нормально.
// package.json
{
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
}
...
}
// webpack.config.js
module.exports = {
...,
devServer: {
publicPath: '/dist'
}
}
модуль
CommonJs
node.js
будетjavascript
Язык используется для программирования на стороне сервера, где требуется модульность из-за взаимодействия с операционной системой и другими приложениями на стороне сервера, в то время какnode.js
частьcommonjs
спецификации, и на ее основе были внесены некоторые коррективы.
После с серверным модулем начал развиваться и клиентский модуль. Однако между модулями сервера и клиента есть большая разница.Все модули сервера хранятся на локальном жестком диске и могут загружаться синхронно.Время ожидания - это время чтения жесткого диска, но для браузеры, будет очень серьезная проблема.Так как модули все на стороне сервера, время ожидания зависит от скорости интернета.Если время ожидания большое, браузер будет в подвешенном состоянии. Поэтому модули на стороне браузера не могут быть загружены синхронно, а могут быть загружены только асинхронно.
Экспорт — это единственный способ показать модуль внешнему миру,commonjs
прошедшийexports
илиmodule.exports
Экспортируйте содержимое в модуль. Его внутренний механизм будетexports
указал наmodule.exports
,иmodule.exports
Пустой объект при инициализации. можно понимать какcommonjs
Следующий код добавляется по умолчанию в заголовок каждого модуля. Будьте осторожны, чтобы не датьexports
Присваивание приведет к тому, что его указание сломается, и не смешивайте их. Также оператор экспорта не представляет конец модуля, вexports
илиmodule.exports
Код позади выполняется как обычно, но обычно помещается в конец модуля.
var module = {
exports: {}
}
var exports = module.exports
commonjs
используется вrequire
модуль импорта,require
Импорт делится на два случая.Если модуль импортируется в первый раз, то будет выполнен его внутренний код, и одновременно будет экспортироваться указанное содержимое.Если модуль был импортирован, внутренний код модуля будет не будет выполняться повторно, но последнее выполнение будет напрямую экспортировано результаты, полученные позже.
Внутри модуляmodule
объект имеет свойствоloaded
Используется для записи того, загружен ли этот модуль, значение по умолчаниюfalse
, который устанавливается при первой загрузке или выполнении модуляtrue
, загрузите снова, чтобы проверитьmodule.loaded
заtrue
больше не будет выполняться. Выполнить следующим образомnode index.js
будет выводитьfalse
true
.
// func.js
console.log(module.loaded)
module.exports = function() {
return module.loaded
}
// index.js
const func = require("./func.js")
console.log(func())
ES6 Module
ES6 Module
Он также рассматривает каждый файл как модуль, каждый модуль имеет свою собственную область видимости, разница заключается в операторах импорта и экспорта.ES6 Module
Строгий режим используется автоматически, независимо от того, начинается ли модуль с'use strict'
, будет использовать строгий режим.
Модули экспорта включают экспорт по умолчанию и именованный экспорт. Импорт именованных модулей экспорта требует деконструкции переменных, а импорт модулей экспорта по умолчанию может принимать любое имя переменной. Обратите внимание, что эффект от импорта переменной эквивалентен объявлению переменной в текущей области, и ее нельзя изменить, то есть все импортированные переменные доступны только для чтения.
Разница между модулем CommonJS и ES6
Самое существенное различие между ними состоит в том, чтоCommonJs
Зависимости от модулей являются динамическими, т. е. установление зависимостей модулей происходит на этапе выполнения кода, в то время какES6 Module
Зависимости от модулей являются статическими, то есть установление зависимостей модулей происходит на этапе компиляции кода.
CommonJs
Путь к модулю может быть указан динамически, поддерживает входящие выражения или может быть передан черезif
оператор, чтобы определить, следует ли загружать модуль. Таким образом, вCommonJs
До выполнения модуля невозможно определить четкие зависимости, поэтому импорт и экспорт модуля происходят на этапе выполнения кода.
ES6 Module
Операторы импорта и экспорта являются декларативными, путь импорта не поддерживается в виде выражения, а операторы импорта и экспорта должны находиться в области видимости модуля верхнего уровня. которыйES6 Module
представляет собой статическую модульную структуру, вES6
Зависимости модуля можно проанализировать на этапе компиляции кода.
ES6 Module
относительноCommonJS
Имеет следующие преимущества.
- Обнаружение и исключение мертвого кода, вы можете использовать инструменты статического анализа, чтобы определить, какие модули не были вызваны. При обращении к библиотеке классов инструмента, как правило, в проекте используется только часть компонентов или интерфейсов, которые могут быть полностью загружены, а код модуля, который не был вызван, никогда не будет выполнен и станет мертвым кодом. Инструменты статического анализа могут удалять неиспользуемые модули во время упаковки, чтобы уменьшить размер ресурсов упаковки.
- проверка типа переменной модуля,
ES6 Module
Структура статического модуля помогает гарантировать, что значения или типы интерфейса, передаваемые между модулями, имеют правильный тип. - оптимизация компилятора,
ES6 Module
Поддерживает прямой импорт переменных, снижает опорные уровни и повышает эффективность программы.
скопировать и связать
какCommonJs
изmodule.exports
Экспорт — это примитивный тип данных, импорт — это просто копия значения. Вывод после запуска следующего:1
1
2
,так какindex.js
серединаcount
правдаadd.js
серединаcount
копия значения , вызовadd
функция, хотя и измененнаяadd.js
серединаcount
значение, но не влияет на значение, созданное во время импортаcount
Копирование влияет.
// add.js
var count = 1
module.exports = {
count,
add() {
count++
},
get() {
return count
}
}
// index.js
const { count, add, get } = require("./add.js")
console.log(count)
add()
console.log(count)
console.log(get())
какmodule.exports
Экспорт — это эталонный тип данных, импорт — это копия эталона. Вывод после запуска следующего:{count: 1}
{count: 2}
true
,так какindex.js
серединаobject
правдаadd.js
серединаobject
копия справки, позывнойupdateObject
измененныйadd.js
серединаobject.count
значение, тоindex.js
серединаobject.count
изменится соответственно.
// add.js
const object = {
count: 1
}
module.exports = {
object,
updateObject() {
object.count++
},
getObject() {
return object
}
}
// index.js
const { object, updateObject, getObject } = require("./add.js")
console.log(object)
updateObject()
console.log(object)
console.log(getObject() === object)
ES6 Module
Импортируемая переменная всегда указывает на переменную внутри модуля, и при ее использовании можно получить самое последнее значение переменной. Вывод после запуска следующего:1
2
2
,index.js
серединаcount
иadd.js
серединаcount
Связь связывания устанавливается между (binding
), самое последнее значение привязки можно получить в режиме реального времени.
// add.js
export var count = 1
export function add() {
count++
}
export function get() {
return count
}
// index.js
import { count, add, get } from "./add.js"
console.log(count)
add()
console.log(count)
console.log(get())
Уведомлениеexport default
Отношения привязки не будет.После выполнения следующего результата будет1
1
2
.
// add.js
var count = 1
export default count
export function add() {
count++
}
export function get() {
return count
}
// index.js
import count, { add, get } from "./add.js"
console.log(count)
add()
console.log(count)
console.log(get())
Во-первыхexport default
— это синтаксический сахар, упрощающий объем кода, когда модуль имеет только один экспорт. следующееexport default
экспортировать переменную примитивного типаcount
.
var count = 1
export default count
ПотомJavaScript
изменит переменнуюcount
во внутреннюю переменную*default*
, затем переименуйте его вdefault
экспорт.
var count = 1
var *default* = count
export { *default* as default }
Доexport default
Причина отсутствия отношений связывания связана с преобразованием синтаксического сахара,index.js
серединаcount
То, что на самом деле связано,add.js
внутренние переменные в*default*
, вместоcount
.
// add.js
var count = 1
var *default* = count
export { *default* as default }
...
// index.js
import { default as count } from './add.js'
...
CommonJs
При импорте переменной модуля это просто копия значения или ссылки. иES6 Module
Импортированные переменные всегда будут связывать переменные внутри модуля, формируя отношение привязки (binding
),Уведомлениеexport default
Экспортируемые переменные не имеют отношений привязки, причина в том, чтоJavaScript
Это вызвано преобразованием синтаксического сахара.
круговая зависимость
Циклические зависимости относятся к модулямA
зависит от модуляB
, а модульB
зависит от модуляA
. Когда сложность проекта в ежедневной разработке возрастает до достаточного масштаба, склонны появляться скрытые циклические зависимости.
как следуетCommonJs
Циклическая зависимость в , выводmodule foo exports {}
module bar exports bar.js
. во-первыхindex.js
импортировать и выполнятьfoo.js
,foo.js
импортировать и выполнятьbar.js
,Потомbar.js
импортировать вfoo.js
, так как он был импортированfoo.js
Но выполнение не завершено, значение экспорта в это время является пустым объектом по умолчанию, и результат печатаетсяbar.js
Законченный. окончательное право исполненияfoo.js
, процесс печати результата заканчивается.
// index.js
require("./foo.js")
// foo.js
const bar = require("./bar.js")
console.log("module bar exports ", bar)
module.exports = "foo.js"
// bar.js
const foo = require("./foo.js")
console.log("module foo exports ", foo)
module.exports = "bar.js"
webpack
Упаковка приведенного выше кода может быть упрощена следующим образом. когдаbar.js
импортировать сноваfoo.js
, прямой возвратinstalledModules
Значение в , которое в данном случае является пустым объектом.
(function(modules) {
var installedModules = {}
function require(moduleId) {
if (installedModules[moduleId]) {
return installedModules[moduleId].exports
}
var module = (installedModules[moduleId] = {
i: moduleId,
exports: {}
})
modules[moduleId].call(module.exports, module, module.exports, require)
return module.exports
}
return require("./index.js")
})({
"./bar.js": function(module, exports, require) {
const foo = require("./foo.js")
console.log("module foo exports ", foo)
module.exports = "bar.js"
},
"./foo.js": function(module, exports, require) {
const bar = require("./bar.js")
console.log("module bar exports ", bar)
module.exports = "foo.js"
},
"./index.js": function(module, exports, require) {
require("./foo.js")
}
})
как следуетES6 Module
Круговая зависимость , выходной результатmodule foo exports undefined
module bar exports bar.js
.bar.js
тоже не могу получитьfoo.js
производное значение , сCommonJS
Экспорт пустых объектов по умолчанию отличается, на этот разundefined
.
// index.js
import foo from "./foo.js"
// foo.js
import bar from "./bar.js"
console.log("module bar exports ", bar)
export default "foo.js"
// bar.js
import foo from "./foo.js"
console.log("module foo exports ", foo)
export default "bar.js"
ИспользоватьES6 Module
Особенности креплений, модифицированные круглые крепления. во-первыхindex.js
импортировать и выполнятьfoo.js
,foo.js
импортировать и выполнятьbar.js
,bar.js
Импортироватьfoo.js
, так как в это времяfoo.js
не завершен,foo
все еще дляundefined
,Потомbar.js
Функция экспорта, возврат права на выполнениеfoo.js
,foo.js
Снова экспортируйте функцию и верните право на выполнениеindex.js
, и, наконец, выполнитьfoo
функция, которая будет выполняться из-за отношения привязкиfoo.js
внутренняя функция, воляinvoked
установлен вtrue
, а затем выполнитьbar.js
функция,bar
Функция выполняется сноваfoo
функционировать, но из-заfoo.js
Внутриinvoked
заtrue
,foo
Функция не выполняется, поэтому порядок выполненияfoo
bar
foo
.
// index.js
import foo from "./foo.js"
foo()
// foo.js
import bar from "./bar.js"
var invoked = false
export default function() {
if (!invoked) {
invoked = true
bar()
console.log("module bar exports ", bar)
}
}
// bar.js
import foo from "./foo.js"
export default function() {
console.log("module foo exports ", foo)
foo()
}
AMD
AMD
То есть он поддерживает спецификацию модуляризации на стороне браузера, а метод загрузки модулей является асинхронным, и выполнение последующих операторов не будет затронуто при загрузке модуля.RequireJS
ДостигнутоAMD
Спецификация.
определяетAMD
модуль, каталог включаетindex.html
иindex.js
,foo.js
,bar.js
модуль.require.js
Модули могут бытьcdn
способ представить,data-main
Указывает основной файл модуля.
require
Импортируйте модуль, параметры — массив загруженного модуля и функция обратного вызова, которая будет выполняться после загрузки модуля.
define
Определить модуль.Параметры - это имя текущего модуля, зависимости текущего модуля и значение экспорта модуля (функция или объект, если это функция, экспортировать возвращаемое значение функции, если это объект , экспортируйте его напрямую).
AMD
По сравнению со стандартным модулем с синхронной загрузкой синтаксис более подробный, а метод загрузки не такой понятный, как при синхронной загрузке.
// index.html
...
<body>
<p>hello world</p>
<script src="./require.js" data-main="./index.js"></script>
</body>
// index.js
require.config({
paths: {
"foo": "./foo",
"bar": "./bar"
}
})
require(["foo"], function (foo) {
console.log('module foo exports ', foo)
}, function (err) {
console.log(err)
})
// foo.js
define('foo', ['bar'], function (bar) {
console.log('module bar exports ', bar)
return 'foo.js'
})
// bar.js
define('bar', function () {
return 'bar.js'
})
CMD
CMD
Это еще одна спецификация модульности на стороне браузера, а также модуль асинхронной загрузки.SeaJs
ДостигнутоCMD
Спецификация.
AMD
Порядок выполнения и порядок записи нескольких зависимых модулей не согласованы, в зависимости от скорости сети, какой из них загружается первым, а какой выполняется первым, а основная логика выполняется после загрузки всех зависимостей.
CMD
при встречеrequire
Соответствующий модуль выполняется только тогда, когда выполняется оператор, и порядок его выполнения и порядок записи точно такие же.
AMD
зависит от предпосылки,CMD
Это близкая зависимость.RequireJS
иSeaJs
Оба предварительно загружают зависимые модули перед выполнением модулей, но время выполнения зависимых модулей отличается.RequireJs
выполняется под нагрузкой, аSeajs
выполняется при использовании.
RequireJs
Используйте массив зависимостей, чтобы найти фактический путь, соответствующий каждому элементу, на основе сведений о конфигурации для предварительной загрузки. иSeajs
Используйте регулярные выражения для захвата внутреннихrequire
поле, которое также предварительно загружается в соответствии с фактическим путем информации о конфигурации для поиска файла.
// index.html
...
<body>
<p>hello world</p>
<script src="./sea.js"></script>
<script src="./index.js"></script>
</body>
// index.js
seajs.config({
paths: {
foo: "./foo",
bar: "./bar"
}
})
seajs.use(['foo'], function (foo) {
console.log('module foo exports ', foo)
})
// foo.js
define(function (require, exports, module) {
var bar = require('bar')
console.log('module bar exports ', bar)
module.exports = 'foo.js'
})
// bar.js
define(function (require, exports, module) {
module.exports = 'bar.js'
})
UMD
UMD
этоJavaScript
Общая спецификация определения модуля, которую можно использовать вJavaScript
работать во всех операционных средах.
одиночный модуль
немодульная среда
Немодульные среды обычно монтируют свойства через глобальный объект. вfoo.js
Чтобы выполнить функцию немедленно,factory
Возвращаемое значение фабричной функции монтируется в глобальный объект,root
является глобальным объектом, значение которого равноwindow
илиglobal
, определяется операционной средой.
// index.html
...
<body>
<p>hello world</p>
<script src="./foo.js"></script>
<script src="./index.js"></script>
</body>
// foo.js
(function (root, factory) {
root.foo = factory()
})(this, function () {
return 'foo.js'
})
// index.js
console.log(foo)
AMD
AMD
способ удовлетворитьAMD
Спецификация.
// index.html
...
<body>
<p>hello world</p>
<script src="./require.js" data-main='./index.js'></script>
</body>
// index.js
require.config({
paths: {
"foo": "./foo"
}
})
require(["foo"], function (foo) {
console.log(foo)
}, function (err) {
console.log(err)
})
// foo.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define('foo', factory)
} else {
root.foo = factory()
}
})(this, function () {
return 'foo.js'
})
UMD
UMD
То есть он поддерживает немодульные среды,CommonJS
,AMD
,CMD
Канонический модуль.
// foo.js
(function(root, factory) {
if (typeof module === "object") {
module.exports = factory()
} else if (typeof define === "function" && define.amd) {
define("foo", factory)
} else if (typeof define === "function" && define.cmd) {
define(function(require, exports, module) {
module.exports = factory()
})
} else {
root.foo = factory()
}
})(this, function() {
return "foo.js"
})
многомодульный
UMD
модули зависят от другихUMD
время модуля.
AMD
// index.html
...
<body>
<p>hello world</p>
<script src="./require.js" data-main='./index.js'></script>
</body>
// index.js
require.config({
paths: {
foo: "./foo",
bar: "./bar"
}
})
require(["foo"], function (foo) {
console.log('module foo exports ', foo)
})
// foo.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define('foo', ['bar'], factory)
} else {
root.foo = factory(root.bar)
}
}(this, function (bar) {
console.log('module bar exports ', bar)
return 'foo.js'
}))
// bar.js
(function (root, factory) {
if (typeof define === 'function' && define.amd) {
define('bar', factory)
} else {
root.bar = factory()
}
}(this, function () {
return 'bar.js'
}))
UMD
// foo.js
(function(root, factory) {
if (typeof module === "object") {
var bar = require("./bar")
module.exports = factory(bar)
} else if (typeof define === "function" && define.amd) {
define("foo", ["bar"], factory)
} else if (typeof define === "function" && define.cmd) {
define(function(require, exports, module) {
var bar = require("bar")
module.exports = factory(bar)
})
} else {
root.foo = factory(root.bar)
}
})(this, function(bar) {
console.log("module bar exports ", bar)
return "foo.js"
})(
// bar.js
(function(root, factory) {
if (typeof module === "object") {
module.exports = factory()
} else if (typeof define === "function" && define.amd) {
define("bar", factory)
} else if (typeof define === "function" && define.cmd) {
define(function(require, exports, module) {
module.exports = factory()
})
} else {
root.bar = factory()
}
})(this, function() {
return "bar.js"
})
)
ввод и вывод ресурсов
концепция
-
module
:всеjs
,css
,png
и т.д. файлыmodule
модуль -
chunk
: блок кода,webpack
Модуль, от которого зависит входной файл в процессе упаковки, а модуль зависит от других модулей.Набор вышеуказанных модулей называетсяchunk
-
bundle
: пакетный файл,webpack
Упакуйте сгенерированные исходные файлы
module
,chunk
,bundle
Суть в разных названиях одного и того же набора кодовой логики в разных сценариях преобразования. На этапе написания каждый отдельный файл являетсяmodule
модуль. На этапе упаковки набор, состоящий из всех модулей, от которых зависит входной файл, представляет собойchunk
кодовый блок. После упаковки и вывода каждый исходный файлbundle
пакетный файл.
визуализируйте сцену упаковки, чтобы описать вышеуказанные концепции, гдеwebpack.config.js
Конфигурационный файл выглядит следующим образом, функция плагина только в том, чтобы извлечь его отдельноcss
документ.
// webpack.config.js
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
entry: {
index: "./index.js",
main: "./main.js",
},
output: {
filename: "[name].js",
},
module: {
rules: [
{
test: /\.css$/,
use: [
MiniCssExtractPlugin.loader,
"css-loader"
],
},
],
},
plugins: [
new MiniCssExtractPlugin({
filename: "[name].css",
}),
],
}
Входные файлы соответственноindex.js
иmain.js
,вindex.js
представилindex.css
стиль иutils
функция класса полезности,mian.js
является отдельным модулем.
// index.js
import './index.css'
import { log } from './utils.js'
log('index.js')
// index.css
p {
background: blue;
}
// utils.js
export function log(val) {
console.log(val)
}
// main.js
console.log('main.js')
Примечание может быть связано с некоторыми плагинами иloader
версия сwebpack
Разница в зависимости версии приводит к ошибке упаковки.Возможно следующееpackage.json
документ.
// package.json
{
...
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3",
"css-loader": "^0.28.9",
"mini-css-extract-plugin": "^0.5.0"
}
}
Выполните команду упаковки для завершения, результат будет следующим.
Исходный модульindex.css
,utils.js
,index.js
иmain.js
, этап упаковкиindex.js
,index.css
иutils.js
кодовый блокchunk 0
,main.js
Составьте блоки кодаchunk 1
, после упаковки выводаindex.css
,index.js
иmain.js
Оба являются пакетными файлами.
—— module ———— chunk ———— bundle
index.css index.css
\ /
utils.js —— chunk 0 —— index.js
/
index.js
main.js —— chunk 1 —— main.js
Вход
entry
То есть путь к файлу записи,webpack
Начните упаковку на основе этого.
Если вы передаете строку или массив строк,chunk
будет названmain
.
Если передается объект, ключ для каждого свойства будетchunk
Название.
Тип строки
module.exports = {
entry: './index.js',
...
}
тип массива
module.exports = {
entry: ['./main.js', './index.js'],
...
}
тип объекта
module.exports = {
entry: {
index: './index.js',
main: './main.js'
},
...
}
тип функции
Тип функции может возвращать любой из вышеперечисленных типов.Преимущество в том, что часть динамической логики может быть добавлена внутрь тела функции для получения записи проекта, а также функция поддерживает возвратPromise
объект для выполнения асинхронных операций.
module.exports = {
entry: () => "./index.js",
}
module.exports = {
entry: () =>
new Promise((resolve, reject) => {
setTimeout(() => {
resolve("./index.js")
}, 5000)
})
}
экспорт (выход)
filename
— это имя файла выходного ресурса, которое имеет форму строки, которая может быть относительным путем, если директория в пути не существует, тоwebpack
Этот каталог создается при экспорте ресурсов. После того, как следующая упаковка будет завершена, она будет создана в корневом каталогеbuild
папка.
module.exports = {
...
output: {
filename: '../build/index.js',
}
}
webpack
Также поддерживается форма, похожая на язык шаблонов, для динамического создания имен файлов. следующееfilename
серединаname
будет заменен наchunk name
, т. е. ресурс, генерируемый конечным проектом, равенindex.js
иmain.js
.
module.exports = {
entry: {
index: './index.js',
main: './main.js'
},
output: {
filename: '[name].js',
}
...
}
filename
Ниже приведены некоторые общие переменные шаблона элемента конфигурации. Его эффект заключается в том, что при наличии несколькихchunk
существуют для разныхchunk
дифференцировать. Другая роль заключается в управлении кэшированием на стороне клиента.chunkhash
иchunk
содержание имеет непосредственное отношение, когдаchunk
При изменении содержимого имя файла ресурсов будет изменено одновременно, и пользователь сразу загрузит новую версию, не используя локальный кеш, когда пользователь запросит файл ресурсов в следующий раз.
-
hash
:webpack
Генерируется путем упаковки всех ресурсовhash
-
id
:Текущийchunk
изid
-
chunkhash
:Текущийchunk
содержаниеhash
path
path
Используется для указания пути вывода ресурса, и значение должно быть абсолютным путем.Установите расположение вывода ресурса в проекте следующим образом.lib
содержание.webpack4+
Версия по умолчаниюdist
Каталог, если не изменен выходной путь, в противном случае его не нужно настраивать отдельно.
const path = require('path')
module.exports = {
...
output: {
...
path: path.join(__dirname, 'lib'),
}
}
publicPath
path
Используется для указания выходного местоположения ресурса,publicPath
Используется для указания запрошенного местоположения ресурса.
Запрошенное местоположение определяетсяjs
илиcss
Запрошенный непрямой путь к ресурсу, напримерhtml
загруженscript
, или загружаются асинхронноjs
,css
запрошенные фотографии и т. д.,publicPath
То есть указать место запроса вышеуказанного ресурса.
Визуализируйте сцену упаковки, чтобы описать описанную выше ситуацию, когда корневой каталог включаетindex.html
,index.js
и другие документы.index.html
Для файла шаблона роль плагина заключается в упаковке упакованногоjs
файл вставляется в шаблон.
// index.html
<html lang="zh-CN">
...
<body>
<div id="app">hello world</div>
</body>
</html>
// index.js
console.log('index.js')
// package.json
{
...
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "^4.29.4",
"webpack-cli": "^3.2.3",
"html-webpack-plugin": "^3.2.0"
}
}
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
filename: 'index.js',
publicPath: '/lib/',
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
})
]
}
бегатьnpm run build
После упаковки он будет сгенерирован в текущем корневом каталоге.dist
папка, которая включаетindex.html
иindex.js
.
// index.html
<html lang="zh-CN">
...
<body>
<div id="app">hello world</div>
<script type="text/javascript" src="/lib/index.js"></script>
</body>
</html>
VS Code
Установка редактораLive Sever
Плагин для эмуляции на этой машинеindex.html
Реальная сцена развернута на сервер,index.html
Щелкните правой кнопкой мыши внутриOpen with Live Server
Запустите локальную службу и откройте интерфейс отладки браузера.Network
Элементы можно просмотреть следующим образомjs
запрос, которыйRequest URL
То есть запрос местоположения ресурса.
publicPath
Разница в итоге приведет к разным адресам запросов ресурсов, гдеpublicPath
Разделенный на следующие три формы, текущийindex.html
Адрес файлаhttp://127.0.0.1:5500/dist/index.html
, имя ресурсаindex.js
.
-
html
Связанный: Пути ресурсов против.html
Ассоциация каталога файлов, то есть путь к ресурсуhtml
путь к каталогу плюсpublicPath
и имя файла
———— publicPath ———————— Request URL
'' http://127.0.0.1:5500/dist/index.js
'./js' http://127.0.0.1:5500/dist/js/index.js
'../assets/' http://127.0.0.1:5500/assets/index.js
- Относится к корневому каталогу: если
publicPath
от'/'
запускается, путь к ресурсу основан на пути к корневому каталогу страницы
———— publicPath ———————— Request URL
'/' http://127.0.0.1:5500/index.js
'/js' http://127.0.0.1:5500/js/index.js
'/dist/' http://127.0.0.1:5500/dist/index.js
- Абсолютный путь: в случае абсолютных путей статические ресурсы обычно помещаются в
CDN
выше
———— publicPath ———————— Request URL
'https://cdn.com/' https://cdn.com/index.js
'//cdn.com/' http://cdn.com/index.js
devServer.publicPath
devServer
В конфигурации также естьpublicPath
, роль которого заключается в указанииdevServer
Путь службы статического ресурса или расположение, в котором указанный ресурс упакован в память.
При запускеdevServer
Ресурсы упакованы в память,devServer
Он отправится в память, чтобы найти упакованный файл ресурсов, а затем перейдет в локальный каталог, чтобы найти содержимое,devServer.contentBase
Вы можете контролировать, куда он идет для доступа к ресурсам локального каталога.
contentBase
По умолчанию используется текущая рабочая директория, если ресурс в памяти не найден, он перейдет вcontentBase
Найти в.
Если не указаноdevServer.publicPath
,devServer
получитеoutput.publicPath
Значение , чтобы избежать несоответствий между средой разработки и производственной средой, обычно сохраняютdevServer.publicPath
иoutput.publicPath
то же или не указаноdevServer.publicPath
.
препроцессор
webpack
может только справитьсяJavaScript
иJSON
файл, для других ресурсов, таких какcss
, изображения или другие наборы синтаксисаts
Нет возможности его загрузить.loader
позволятьwebpack
Возможность обработки других типов файлов и преобразования их вwebpack
Модуль, который может получать, загружается,loader
По сути, это предварительная обработка.
Каждыйloader
по сути является функцией, грубо говоря, в видеoutput = loader(input)
,input
для конвертируемого модуля,output
Для преобразованного модуля используйтеbabel-loader
будетES6+
код преобразуется вES5
, приведенная выше формаES5 = babel-loader(ES6+)
.loader
можно связать, т.е.loader
Выход можно использовать как другойloader
ввод в видеoutput = loaderA(loaderB(input)))
.
loader
включаютtest
иuse
два свойства,test
Используется для определения того, какие файлы будут преобразованы,use
Определяет, какой из них следует использовать при преобразованииloader
.
элемент конфигурации
options
loader
Обычно некоторые элементы конфигурации предоставляются, как правило, черезoptions
чтобы передать его, конкретныйloader
отличается от того, что он предлагаетoptions
Тоже разные.
module.exports = {
...
module: {
rules: [
{
test: /\.js$/,
use: {
loader: 'babel-loader',
options: {
...
}
}
}
]
}
}
exclude/include
Исключать или включать модули в указанном каталоге, принимать регулярные выражения или строки абсолютного пути к файлу. Исключаются следующиеnode_modules
модуль ниже.
{
test: /\.js$/,
exclude: /node_modules/
...
}
include
Указывает, что включены только соответствующие модули, как показано ниже:src
содержание.
{
test: /\.js$/,
include: /src/
...
}
какinclude
иexclude
одновременно существуют,exclude
более высокий приоритет. Исключить следующим образомnode_modules
под все модули.
{
test: /\.js$/,
exclude: /node_modules/,
include: /node_modules\/lodash/
...
}
resource/issuer
resource
является грузополучателем, иissuer
являются загрузчиками, оба из которых могут использоваться для более точного охвата правил модуля.
Следующее толькоsrc
в каталогеjs
На документы можно ссылатьсяcss
.
{
test: /\.css$/,
use: ['style-loader', 'css-loader'],
issuer: {
test: /\.js$/,
include: /src/
}
}
вышеtest
,include
,exclude
Элементы конфигурации распределены по разным уровням, что менее читабельно. Лучше добавитьresource
Объект обертывает внешнюю конфигурацию.
Следующее кромеnode_modules
внизjs
,остальныеjs
можно процитироватьcss
документ. Толькоsrc
в каталогеcss
На документы можно ссылаться.
{
use: ['style-loader', 'css-loader'],
issuer: {
test: /\.js$/,
exclude: /node_modules/
},
resource: {
test: /\.css$/,
include: /src/
}
}
enforce
используется для указанияloader
типы, получать толькоpre
илиpost
Два типа.webpack
серединаloader
Порядок выполнения можно разделить наpre
(приоритет),inline
(вторая обработка),normal
(обычная обработка),post
(окончательная обработка), прямо определенная вышеloader
по умолчаниюnormal
тип,post
иpre
нужно использоватьenfore
указать.
означает следующееeslint-loader
будет во всем нормloader
выполнял раньше. На самом деле не нужно указыватьenforce
Просто гарантияloader
Порядок выполнения правильный, настроитьenforce
Основная цель — сделать правила модуля более понятными и читабельными.
rules: [
{
test: /\.js$/,
enforce: "pre",
use: "eslint-loader",
},
]
Общий загрузчик
sass-loader
sass-loader
даscss
Препроцессор для файлов типов, обрабатывающий их синтаксис и компилирующий вcss
.sass-loader
ядро зависит отnode-sass
,иnode-sass
зависит отnode
, обратите внимание при установкеnode-sass
иnode
Между версиями поддерживаются.
послеcss-loader
иметь дело сcss
Различные синтаксис загрузки@imoprt
илиurl()
функция преобразуется вrequire
. просто поставьcss
модуль загружен вjs
код, фактически не используемый.
Наконец,style-loader
будетjs
Строка стиля обернута какstyle
Вкладки вставляются на страницу.
Вышеуказанные сценарии обработки следующие, корневой каталог включаетindex.js
,index.scss
,index.html
,package.json
Ждать.
// package.json
{
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3",
"webpack-dev-server": "3.1.14",
"html-webpack-plugin": "3.2.0",
"css-loader": "^0.28.9",
"style-loader": "^0.19.0",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.7"
}
}
// index.scss
$color: red;
p {
color: $color;
}
// index.js
import './index.scss'
// index.html
<html lang="zh-CN">
...
<body>
<p>hello world</p>
</body>
</html>
// webpack.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry: './index.js',
output: {
filename: 'index.js'
},
module: {
rules: [
{
test: /\.scss$/,
use: ['style-loader', 'css-loader', 'sass-loader'],
}
],
},
plugins: [
new HtmlWebpackPlugin({
template: './index.html',
})
],
mode: 'development',
}
бегатьnpm run dev
, откройте страницу для просмотраcss
стили были введены вhtml
бинго.
babel-loader
babel-loader
используется для обработкиES6+
и скомпилировать его какES5
, чтобы он мог использовать новейшие языковые функции в проекте, не беспокоясь о совместимости этих функций на разных платформах.
Установитьbabel
необходимо установить одновременноbabel-loader
,@babel/core
и@babel/preset-env
. в@babel/core
даbabel-loader
Зависимые модули ядра,@babel/preset-env
Это официально рекомендуемый префаб, который может автоматически добавлять необходимые плагины и исправления для компиляции в соответствии с целевым браузером или операционной средой, настроенной пользователем.ES6+
код,babel-loader
Вызывается как промежуточный мост@babel/core
изapi
рассказатьwebpack
что делатьjs
.
{
test: /\.js$/,
loader: 'babel-loader',
exclude: /node_modules/,
options: {
cacheDirectory: true,
presets: [
['@babel/preset-env', { modules: false }]
]
},
}
babel-loader
обычно компилирует всеjs
модуль, который серьезно замедлит скорость упаковки и может изменить исходное поведение сторонних модулей, поэтому необходимоexclude
исключатьnode_modules
.
cacheDirectory
Включение механизма кеша при переупаковке неизмененных модулей попытается прочитать кеш, избегая высокопроизводительного процесса перекомпиляции.cacheDirectory
получить путь типа string илиtrue
,заtrue
будет использовать каталог кеша по умолчанию, когдаnode_modules/.cache/babel-loader
.
@babel/preset-env
будетES6 Mudule
превратиться вCommonJs
, приведет кwebpack
изtree-shaking
недействительно, можно установитьmodules
заfalse
вместо этого отключите это поведениеES6 Module
преобразование вwebpack
иметь дело с.
babel-loader
Также поддерживает внешний.babelrc
конфигурационный файл, будетpresets
иplugins
извлечено.
// .babelrc
{
"presets": [
["@babel/preset-env", { "modules": false }]
]
}
url-loader
url-loader
Модуль для упаковки типов файлов менее чем заlimit
Порог изображения для обработки и преобразования его вbase64
кодирование.
Конвертировать картинкуbase64
В код введена кодировка, что позволяет уменьшить количество запросов и повысить производительность страницы. но и увеличитьjs
илиhtml
Размер файла большой, и изображения используются в проекте много раз, и каждое опорное место будет создано.base64
кодирования, что приводит к избыточности кода. С другой стороны, браузеры могут кэшироватьhttp
запрошенное изображение. Поэтому его нужно сбалансировать и установить разумно.limit
порог.
{
test: /\.(png|jpg|gif)$/,
use: {
loader: 'url-loader',
options: {
limit: 10240
}
}
}
file-loader
file-loader
Также используется для упаковки модулей файлового типа,url-loader
Изображения, превышающие пороговое значение, которые не могут быть обработаны, передаются вfile-loader
Обработайте, выведите ресурс в каталог упаковки в соответствии с конфигурацией.
{
test: /\.(png|jpg|gif)$/,
use: [
{
loader: 'file-loader',
options: {
name: 'img/[name].[hash:8].[ext]'
}
},
],
}
vue-loader
vue-loader
используется для обработкиvue
файл, извлекитеtemplate/script/style
код, а затем передать их соответствующемуloader
иметь дело с. вcss-loader
иметь дело сstyle
код стиля,vue-template-compiler
ответственный заtemplate
Шаблон компилируется вrender
функция визуализации,vue-loader
Поддержка по умолчаниюES6
, каждыйvue
Компоненты могут быть созданыcss
размах и т.д.
использоватьvue-loader
Сценарий следующий, корневой каталог включаетindex.html
,index.js
,App.vue
и другие документы.
// package.json
{
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3",
"webpack-dev-server": "3.1.14",
"html-webpack-plugin": "3.2.0",
"css-loader": "^0.28.9",
"vue": "^2.5.13",
"vue-loader": "^14.1.1",
"vue-template-compiler": "^2.5.13"
}
}
// index.js
import Vue from "vue"
import App from "./App.vue"
new Vue({
el: "#app",
render: (h) => h(App),
})
// index.html
<html lang="zh-CN">
...
<body>
<div id="app"></div>
</body>
</html>
// App.vue
<template>
<h1>{{ title }}</h1>
</template>
<script>
export default {
name: "app",
data() {
return {
title: "hello world",
}
}
}
</script>
<style lang="css">
h1 {
color: blue;
}
</style>
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
module.exports = {
entry: "./index.js",
output: {
filename: "[name].js",
},
module: {
rules: [
{
test: /\.vue$/,
use: "vue-loader",
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
}),
],
mode: "development",
}
бегатьnpm run dev
,App.vue
был установлен наdiv#app
элемент,h1
Шаблон в также отображается какhello world
.
пользовательский загрузчик
инициализация
Пользовательская реализация одногоloader
, для всехjs
файл с включенным строгим режимом, т.е. добавление в его заголовок'use strict'
.
Создайтеstrict-loader
каталог, выполнитьnpm init
Инициализировать каталог, создатьloader
основной файлindex.js
.
// index.js
module.exports = function(content) {
var useStrictPrefix = "'use strict'\n\n"
return useStrictPrefix + content
}
webpack
Технические ссылкиstrict-loader
,вuse.loader
ссылка на абсолютный путьstrict-loader
, можно изменить в любое времяloader
отладка исходного кода в .
// webpack.config.js
module.exports = {
entry: "./index.js",
output: {
filename: "[name].js",
},
module: {
rules: [
{
test: /\.js$/,
use: {
loader: "F:/strict-loader",
},
},
],
},
devtool: "none",
mode: "development"
}
// package.json
{
...
"scripts": {
"build": "webpack"
},
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3"
}
}
// index.js
console.log("hello world")
Выполнение проектаnpm run build
, часть исходного кода после упаковки и вывода выглядит следующим образом.
включить кеш
Когда входные файлы и другие зависимости не изменились, кеш следует использовать напрямую, а не повторять работу по преобразованию.
// strict-loader/index.js
module.exports = function(content) {
if (this.cacheable) {
this.cacheable()
}
var useStrictPrefix = "'use strict'\n\n"
return useStrictPrefix + content
}
параметр опций
loader
Элементы конфигурации могут бытьuse.options
пройти в. необходимо установитьloader-utils
Библиотека зависимостей с некоторыми вспомогательными функциями, предоставляемыми ею.
npm i loader-utils@1.1.0 --save
loader
Получатьoptions
Способ следующий.
// strict-loader/index.js
var loaderUtils = require("loader-utils")
module.exports = function (content) {
...
var options = loaderUtils.getOptions(this) || {}
console.log("options", options)
...
}
обработка стиля
Отдельные файлы стилей
style-loader
Оберните строку стиля какstyle
теги вставляются на страницу, но в рабочей среде вы хотите, чтобы стили существовали вcss
файл вместоstyle
тег, потому что файл более удобен для кэширования на стороне клиента.
webpack4-
В основном используетсяextract-text-webpack-plugin
плагин для извлечения стилей вcss
документ.
единый стиль
Корневой каталог включаетindex.html
,index.js
,index.css
и другие документы. будет следующимindex.js
упакован вindex.html
в, из нихwebpack.config.js
серединаExtractTextPlugin.extract
серединаuse
Используется, чтобы указать, какие стили взять перед извлечениемloader
для предварительной обработки,fallback
Используется для указания того, что использовать, когда плагин не может извлечь стили.loader
,new ExtractTextPlugin
Параметр определяет имя выходного файла.
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
const ExtractTextPlugin = require("extract-text-webpack-plugin")
module.exports = {
entry: './index.js',
output: {
filename: "[name].js",
},
module: {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin.extract({
fallback: "style-loader",
use: "css-loader",
}),
},
],
},
plugins: [
new ExtractTextPlugin("index.css"),
new HtmlWebpackPlugin({
template: "./index.html",
}),
],
mode: "development"
}
// package.json
{
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3",
"webpack-dev-server": "3.1.14",
"html-webpack-plugin": "3.2.0",
"css-loader": "^0.28.7",
"style-loader": "^0.19.0",
"extract-text-webpack-plugin": "^4.0.0-beta.0"
}
}
// index.html
<html lang="zh-CN">
...
<body>
<p>hello world</p>
</body>
</html>
// index.js
import "./index.css"
// index.css
p {
color: blue;
}
бегатьnpm run dev
, чтобы увидеть, что извлеченные файлы ссылаются наindex.html
середина.
несколько файлов
Когда имеется несколько файлов ввода, и разные файлы ввода представляют разныеcss
стили, извлечь несколькоcss
Стили следующие. Корневой каталог включаетfoo.js
,foo.css
,bar.js
иbar.css
.
// foo.js
import "./foo.css"
// foo.css
p {
color: blue;
}
// bar.js
import "./bar.css"
// bar.css
h5 {
color: red;
}
// index.html
<html lang="zh-CN">
...
<body>
<p>hello</p>
<h5>world</h5>
</body>
</html>
package.json
Зависимость соответствует одному файлу,webpack.config.js
Небольшая регулировка. следующее[name].css
серединаname
относится кchunk name
,Сейчасentry
Имя, присвоенное записи (foo
,bar
).
// webpack.config.js
module.exports = {
entry: {
foo: "./foo.js",
bar: "./bar.js",
},
...
plugins: [
new ExtractTextPlugin("[name].css"),
...
],
}
бегатьnpm run dev
, вы можете видеть, что несколько извлеченных файлов ссылаются наindex.html
середина.
какindex.js
прошедшийimport()
загружается асинхронноfoo.js
,foo.js
загружен вfoo.css
, то в конце концовfoo.css
могут быть загружены только синхронно или могут быть загружены только сstyle
Вставьте этикетку вhtml
, не может быть загружен по требованию.
нагрузка по требованию
Webpack4+
в основном используютmini-css-extract-plugin
извлекатьcss
стили, которые можно динамически вставлятьlink
Теги загружаются по запросу.
Корневой каталог включаетindex.js
,index.css
,foo.js
иfoo.css
и другие документы.
// webpack.config.js
const HtmlWebpackPlugin = require("html-webpack-plugin")
const MiniCssExtractPlugin = require("mini-css-extract-plugin")
module.exports = {
entry: "./index.js",
output: {
filename: "[name].js",
},
module: {
rules: [
{
test: /\.css$/,
use: [
{
loader: MiniCssExtractPlugin.loader,
},
"css-loader",
],
},
],
},
plugins: [
new HtmlWebpackPlugin({
template: "./index.html",
}),
new MiniCssExtractPlugin({
filename: "[name].css",
chunkFilename: "[id].css",
}),
],
mode: "development",
}
// package.json
{
...
"scripts": {
"dev": "webpack-dev-server",
"build": "webpack"
},
"devDependencies": {
"webpack": "4.29.4",
"webpack-cli": "3.2.3",
"webpack-dev-server": "3.1.14",
"html-webpack-plugin": "3.2.0",
"css-loader": "^0.28.7",
"mini-css-extract-plugin": "^0.5.0"
}
}
// index.js
import "./index.css"
setTimeout(() => {
import("./foo.js")
}, 2000)
// index.css
p {
color: blue;
}
// foo.js
import "./foo.css"
// foo.css
h5 {
color: red;
}
// index.html
<html lang="zh-CN">
...
<body>
<p>hello</p>
<h5>world</h5>
</body>
</html>
бегатьnpm run dev
,2s
Заднийhead
будет динамически вставляться вlink
этикетки иscript
Этикетка.
postcss
postcss-loader
не совсемcss
Препроцессор — это просто платформа для запуска плагинов, и его режим работы — получение исходного кода стиля и отправка его плагину компиляции для обработки и вывода.css
, где плагин компиляции можно указать через конфигурацию.
postcss-loader
postcss-loader
Может использоваться отдельно или сcss-loader
используется в комбинации, когда используется отдельноpostcss-loader
, не рекомендуется использоватьcss
используется в@import
, иначе будет сгенерирован избыточный код.
postcss-loader
нуждаться вcss-loader
иstyle-loader
после использования, но после других препроцессоров (таких какsass-loader
Используйте это раньше.
postcss
Требуется отдельный файл конфигурации, который необходимо создать в корневом каталогеpostcss.config.js
, без добавления каких-либо функций можно временно вернуть пустой объект.
// webpack.config.js
{
test: /\.css/,
use: ['style-loader', 'css-loader', 'postcss-loader'],
}
// package.json
"devDependencies": {
...
"css-loader": "^0.28.7",
"postcss-loader": "^2.1.2",
"style-loader": "^0.19.0"
}
// postcss.config.js
module.exports = {}
autoprefixer
autoprefixer
заcss
Автоматически добавлять префиксы поставщиков браузеров в соответствии сCan I UseДанные определяют, следует ли добавлять префикс к функции.
Корневой каталог включаетindex.css
,index.html
,index.js
иpostcss.config.js
Ждать.
// package.json
"devDependencies": {
...
"autoprefixer": "^8.1.0"
}
// postcss.config.js
const autoprefixer = require('autoprefixer')
module.exports = {
plugins: [
autoprefixer({
grid: true,
browsers: ['> 1%', 'last 3 versions', 'ie 8'],
})
]
}
// index.css
div {
display: grid;
}
// index.js
import './index.css'
упаковано какgrid
добавлена функцияie
префикс.
stylelint
stylelint
Являетсяcss
инструмент обнаружения кода, похожий наeslint
, к которому можно добавить различные правила для унификации качества стиля кода проекта.
postcss.config.js
иpackage.json
,index.css
Части следующие, из которыхdeclaration-no-important
используется в коде!important
стиль выдает предупреждение.
// package.json
"devDependencies": {
...
"postcss-loader": "^2.1.2"
}
// postcss.config.js
const stylelint = require('stylelint')
module.exports = {
plugins: [
stylelint({
config: {
rules: {
'declaration-no-important': true,
},
},
})
],
}
// index.css
div {
color: red !important;
}
Следующее предупреждающее сообщение будет выведено на консоль при выполнении упаковки.
cssnext
cssnext
Вы можете использовать последнюю версию в своем проектеcss
Синтаксические особенности.
// package.json
"devDependencies": {
...
"postcss-cssnext": "^3.1.0"
}
// postcss.config.js
const postcssCssnext = require('postcss-cssnext')
module.exports = {
plugins: [
postcssCssnext({
browsers: ['> 1%', 'last 2 versions'],
})
]
}
// index.css
:root {
--highlightColor: #666;
}
p {
color: var(--highlightColor);
}
Результат после упаковки следующий.
CSS Modules
CSS Modules
представляет собой стильное модульное решение, в котором каждыйcss
Имеет отдельную область действия, не конфликтует с внешним миром и может импортироваться по относительным путям.css
модуль, который может бытьcomposes
повторно использовать другиеcss
модуль.
CSS Modules
Не нужно устанавливать дополнительные модули, открывайтеcss-loader
изmodules
элементы конфигурации.
вlocalIndentName
указать скомпилированныйcss
стиль имени класса,name
относится к имени модуля,local
Относится к исходному идентификатору селектора,hash:base64:5
за5
немногоhash
значение, этоhash
Значение вычисляется из имени и идентификатора модуля.
// webpack.config.js
{
test: /\.css/,
use: [
"style-loader",
{
loader: "css-loader",
options: {
modules: true,
localIdentName: "[name]__[local]__[hash:base64:5]"
}
}
]
}
// index.css
.title {
color: red;
}
// index.js
import style from './index.css'
document.write(`<div class='${style.title}'>hello wolrld</div>`)
Проверьте имя скомпилированного класса после упаковки.
🎉 Напишите в конце
🍻Ребята, если вы видели это и считаете, что эта статья была вам полезна, ставьте лайк 👍 илиStar✨Поддержите!
Кодирование вручную, если есть ошибки, исправьте их в комментариях 💬~
Ваша поддержка — самая большая мотивация для меня обновляться💪~
GitHub,Blog,Наггетс,CSDNСинхронизированное обновление, подписывайтесь 😉~