предисловие
Роль веб-пакета во фронтенд-инжиниринге становится все более важной, и он также является важной частью фронтенд-инжиниринга. В этой статье я научусь пользоваться wbepack по процессу проекта вместе с вами Мама больше не должна переживать, что я не буду пользоваться webpack, и не увижу, где нахожусь. Это вводная статья.
Инжиниринг
Вот проектная и стандартизированная настройка.Если вы одноклассник, который впервые использует веб-пакет, вы все еще смотрите этот фрагмент знаний в конце.
Теперь скаффолдинг, такой как vue и react, будет автоматически отделять файл конфигурации веб-пакета, используемого в среде разработки, от файла конфигурации рабочей среды, а также сжимать код, добавлять версию управления хэшем и другие операции для запуска, когда проект выходит в сеть, что позволяет избежать времени упаковки на этапе разработки слишком длинный вопрос. Например, вот так, разделите файлы конфигурации для двух сред.
Давайте посмотрим на содержимое двух файлов конфигурации (я использую машинописный текст для разработки реакции, пожалуйста, игнорируйте содержимое)
Среда разработки:
Производственная среда:
Видно, что в среду разработки было добавлено несколько подключаемых модулей.Преимущества этого заключаются в большей инженерии и стандартизации, сокращении времени упаковки среды разработки и повышении удобства сопровождения кода.
Написание файлов конфигурации отдельно включает в себя выполнение различных файлов конфигурации с командами. Мы можем использовать команды сценариев npm. Мы можем найти сценарии в package.json и добавить следующую команду «build»: «NODE_ENV=production webpack --config ./webpack.production. config.js --прогресс"
Объясните вам смысл этой команды
- NODE_ENV=production — установить рабочую среду в производственную среду.
- webpack --config — файл конфигурации для запуска webpack
- ./webpack.production.config.js — это файл, который нужно запустить в указанном месте, этот путь относится к корневому каталогу.
- --progress — процент прогресса, отображаемый в процессе компиляции.
Если вы не занимаетесь стандартизацией и инжинирингом, мы просто пишем конфигурационный файл, здесь нет жестких требований. Поговорим о конкретной конфигурации webpack
Начинать
Когда мы не очень хорошо разбираемся в веб-пакете, мы можем не писать полный файл конфигурации и часто добавлять то, что используем.Давайте выполним этот шаг, чтобы научиться тщательно использовать веб-пакет.
module.exports = {
entry: './src/index.js' // 这里是项目入口文件地址
ouput: {
path: __dirname + "/dist", // 这里是项目输出的路径,__dirname表示当前文件的位置
filename: "js/"+"[name].js" // 这里是生成文件的名称,可起你想要的名字
}
}
loader
Это наш первый скелет.Далее мы добавим некоторые конфигурации.Например, если вы используете реакцию, то вам нужно добавить соответствующий загрузчик реакции.В качестве примера возьмем реакцию, написанную на машинописном языке.
module.exports = {
entry: './src/index.js' // 这里是项目入口文件地址
ouput: {
path: __dirname + "/dist", // 这里是项目输出的路径,__dirname表示当前文件的位置
filename: "js/"+"[name].js" // 这里是生成文件的名称,可起你想要的名字
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" }
]
},
}
Языки предварительной обработки CSS/CSS (less, sass, stylus)
Webpack разбивает файлы на модули для компиляции и упаковки, все наши вещи, которые обрабатывают содержимое файлов, должны быть размещены в модулях, а правила есть правила.
Два загрузчика в правилах предназначены для компиляции файлов .tsx и обработки сообщений об ошибках.
После того, как вы написали компоненты, нужно приступить к написанию стилей, но будь то css или языки препроцессинга, такие как less, sass и т. д., вебпак не может справиться с этим напрямую, мы устанавливаем и используем соответствующий загрузчик. Возьмем в качестве примера less и css.
{test: /\.(less|css)?$/, loader: ["style-loader", "css-loader", "less-loader"]}
Webpack будет выполнять загрузчики в порядке справа налево, мы будем меньше разбирать, а затем упаковывать и компилировать CSS. Если вы не используете языки препроцессинга типа less, установите css-loader и style-loader.
- style-loader вставляет css в тег стиля страницы
- css-loader преобразует @import и url() в import/require()
- less-loader должен компилировать меньше файлов в css
postcss решает проблемы совместимости css
Здесь мы пишем, вдруг задумаемся над пунктом, то есть совместимостью стилей CSS.Если писать вручную, то возможно у вас в голове возникнет предложение о том, что mmp не стоит говорить, ха-ха, надо использовать postcss для решения этой проблема.
postcss — это текущее решение для совместимости css. Оно автоматически добавит префиксы, чтобы сделать стили css совместимыми с различными браузерами. Установите и используйте postcss-loader здесь.
{ test: /\.(less|css)?$/, loader: ["style-loader", "css-loader", "less-loader", "postcss-loader"]}
В конце нужно написать postcss-loader (на самом деле его нужно поставить только после css-loader) Как вы думаете, можно ли так написать? Можно только сказать, что слишком молодой, postcss в основном полагается на свой автопрефиксер плагина для решения проблемы совместимости.Нам также нужно написать файл конфигурации postcss.config.js в корневом каталоге, как показано ниже.
module.exports = {
plugins: [
require('autoprefixer')
]
};
При написании этого нам больше не нужно беспокоиться о совместимости с CSS, как и при использовании файла babel, этот файл будет автоматически проанализирован, и нам не нужно об этом заботиться.
Использование svg-изображений
При разработке мы часто сталкиваемся с тем, что некоторые изображения иконок будут искажаться при разных обстоятельствах, а ресурсов слишком много.Нам нужно уменьшить размер изображений иконок.В это время нам нужно внедрить svg,а иконный шрифт Али может использоваться в китайской библиотеке, тем самым вводя значки svg для решения вышеуказанных проблем.
Мы открыли папку с загруженным материалом и обнаружили, что в ней есть несколько файлов .woff, .svg, .eot. Если мы хотим использовать значок svg, мы должны полагаться на эти файлы. В настоящее время веб-пакет не поддерживает эти файлы. , и нам нужно ввести новый загрузчик.
{ test: /\.(woff|svg|eot|ttf)?$/, loader: "url-loader" }
Теперь мы можем с удовольствием использовать значок svg, искажений нет, и он будет очень маленьким.
webpack-dev-server
При написании этого мы можем постоянно упаковывать webpack, что слишком хлопотно, поэтому появился webpack-dev-server. Это сервер, предоставляемый webpack, для установки мы используем npm i webpack-dev-server --save-dev.
На самом деле мы можем открыть его, набрав webpack-dev-server --open в командной строке.По умолчанию это localhost:8080.Теперь нам не нужно повторно использовать команду webpack для упаковки и установки.
Стоит отметить, что файлы, упакованные webpack-dev-server, будут храниться в памяти, поэтому при импорте файлов в index.html у вас должно быть следующее, вот выходной файл по умолчанию — bundle.js
<script src="bundle.js"></script>
Сегодня мы не будем фокусироваться на webpack-dev-server, в будущем я напишу еще одну статью, чтобы подробно объяснить его использование.
Возможно, мы использовали эти функции только на этапе разработки.Поговорим о подготовке к запуску проекта.
Производственная среда
оптимизация
Сжать js-код
Проекты, которые мы упаковываем, часто бывают большими, содержат много пробелов и занимают много места.В настоящее время нам нужно уменьшить размер файла, сжимая js. webpack поставляется с плагином UglifyJsPlugin для сжатия кода js, используйте следующее
plugins: [
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
Наши плагины единообразно размещены в plugins of export.modules = {}, что является массивом, и при использовании плагина можно использовать новый экземпляр. Здесь мы используем экземпляр webpack, поэтому нам нужно указать webpack в начале файла конфигурации, т.е. var webpack = require('webpack');
разделить файл
Когда мы используем js-библиотеки, такие как vue или react, webpack упакует их вместе. Файлы react и react-dom весят сотни килограммов, и все они упакованы в один файл. Вполне возможно, что этот файл будет очень большим. Когда пользователи откроют его впервые часто возникает проблема ожидания длинного белого экрана, в это время нам нужно извлечь такие файлы.
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
Здесь мы будем использовать внешние, которые находятся на том же уровне, что и плагины. Ключ слева представляет зависимость, а значение справа представляет объект, используемый в файле. Например, при разработке react мы часто пишем import React from 'react' в шапке файла.Здесь можно сесть с вышесказанным.
Здесь нам нужно импортировать и использовать этот файл отдельно, добавьте следующий код в index.html
<script src="./node_modules/react/umd/react.xxx.js"></script>
<script src="./node_modules/react-dom/umd/react-dom.xxx.js"></script>
На данный момент мы разделили файл.
Однако у нас невозможно иметь node_modules, когда проект выходит в сеть, поэтому нам нужно использовать плагин копирования для копирования файлов реакции и реакции-дома.
new CopyWebpackPlugin([ // from是要copy的文件,to是生成出来的文件
{ from: "node_modules/react/umd/react.xxx.js", to: "js/react.min.js" },
{ from: "node_modules/react-dom/umd/react-dom.xxx.js", to: "js/react-dom.min.js" }
{ from: "public/favicon.ico", to: "favicon.ico" }
])
Таким образом, наш файл index.html должен быть записан в следующем виде
разделить css
Мы также можем разделить файл css отдельно, преимущество этого в том, что мы можем поместить упакованный файл css в CDN, а затем кэшировать его в клиенте браузера. Это максимально уменьшает размер файла, а также ненужную перезагрузку ресурсов, трату полосы пропускания.
Сначала нам нужно установить плагин
npm install extract-text-webpack-plugin --save-dev
Добавьте соответствующую конфигурацию в файл конфигурации
var ExtractTextPlugin = require("extract-text-webpack-plugin");
Добавить плагины к плагинам
new ExtractTextPlugin("styles.css")
Ниже приводится конкретное использование
module.exports = {
// entry和output自动省略
module: {
loaders: [{
test: /\.css$/,
loader: ExtractTextPlugin.extract('style-loader',
'css-loader!postcss-loader') // 这里我目前使用less还没有成功
}]
},
postcss: function() {
return [autoprefixer, cssnext, precss, cssnano]
},
plugins: [
new ExtractTextPlugin('./css/[name].min.css') // 生成到css文件夹下
]
}
webpack упакует все указанные файлы css и, наконец, сгенерирует файл ./css/[name].min.css.
Обработка изображения
Здесь перекодирование изображения base64 также для уменьшения объема ресурса
Установить URL-загрузчик
npm install url-loader --save-dev
Добавить в правила модулей
{
test: /\.(png|jpg)$/,
loader: 'url?limit=8192&name=images/[hash:8].[name].[ext]'
}
limit устанавливает пороговое значение. Если изображение меньше этого значения, изображение в кодировке base64 будет автоматически включено. Если изображение больше этого значения, оно будет упаковано в путь, соответствующий параметру имени, и имя изображения будет включать 8-битную кодировку md5.имя расширения
Ресурсы кеша браузера
Наш фон установит Cache-Control: max-age=seconds вместо ресурсов, чтобы установить время кеша для ресурсов, что заставляет нас загружать ресурсы в кеш после обновления страницы, но есть проблема, то есть, как только мы обновим страница После обновления версии, если клиент не очистил кеш и срок действия кеша не истек, последние ресурсы не могут быть загружены. На данный момент нам нужно значение хеш-функции для контроля версий.
мы обычно делаем
output: {
path: __dirname + "/dist",
filename: "[name][hash].js"
}
Добавьте [хэш] в выходной файл, чтобы добавить хеш-значение, чтобы, когда пользователь загружает html, был загружен соответствующий хеш-файл упаковки, например следующий
<script type="text/javascript" src="main3d1cb903f77dad5737e9.js"></script>
Упакованный файл js выглядит так
Это решит проблему.
И последний пункт
Мы не можем каждый раз вручную копировать index.html в упакованный файл dist, мы будем использовать плагин html-webpack-plugin
Он может автоматически добавлять файлы html в файлы dist, и в то же время он автоматически добавляет файлы js с хеш-значениями.
Внедрить плагины
var HtmlWebpackPlugin = require('html-webpack-plugin');
Используйте плагины
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.tmpl.html'),
filename: 'index.html'
})
Позвольте мне объяснить вам здесь, что шаблон является шаблоном.Во многих случаях производственная среда и среда разработки различаются, что приводит к различным путям к ресурсам, представленным index.html.Это чтобы изменить его, мы можем создать шаблон, который указывает компиляцию Когда мы копируем файл index.html. имя_файла — это окончательно сгенерированное имя файла.
Файл шаблона выглядит следующим образом
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.ico">
<title>Projection-Web</title>
</head>
<body>
<div id="root"></div>
<script src="js/react.min.js"></script>
<script src="js/react-dom.min.js"></script>
</body>
</html>
Сгенерированный файл index.html выглядит следующим образом.
<!DOCTYPE html>
<html lang="zh">
<head>
<meta charset="UTF-8">
<link rel="icon" href="favicon.ico">
<title>Projection-Web</title>
</head>
<body>
<div id="root"></div>
<script src="js/react.min.js"></script>
<script src="js/react-dom.min.js"></script>
<script type="text/javascript" src="js/main3d1cb903f77dad5737e9.js"></script></body>
</html>
Ниже приведено содержимое папки dist, которую я упаковал и скомпилировал.
Ниже приведен файл конфигурации (часть) производственной среды.
var CopyWebpackPlugin = require("copy-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var webpack = require("webpack");
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
module.exports = {
entry: "./src/index.tsx",
output: {
path: __dirname + "/dist",
filename: "js/"+"[name][hash].js"
},
resolve: {
extensions: [".ts", ".tsx", ".js", ".json"]
},
module: {
rules: [
{ test: /\.tsx?$/, loader: "awesome-typescript-loader" },
{ enforce: "pre", test: /\.js$/, loader: "source-map-loader" },
{ test: /\.(less|css)?$/, loader: ["style-loader", "css-loader", "less-loader", "postcss-loader"] },
{ test: /\.(woff|svg|eot|ttf)?$/, loader: "url-loader" }
]
},
externals: {
"react": "React",
"react-dom": "ReactDOM"
},
plugins: [
new CopyWebpackPlugin([
{ from: "node_modules/react/dist/react.js", to: "js/react.min.js" },
{ from: "node_modules/react-dom/dist/react-dom.js", to: "js/react-dom.min.js" },
{ from: "index.html", to: "index.html" },
{ from: "public/favicon.ico", to: "favicon.ico" }
]),
new HtmlWebpackPlugin({
template: path.join(__dirname, 'src/index.tmpl.html'),
filename: 'index.html'
}),
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false
}
})
]
};
Хорошее изучение webpack — основное качество современного фронтенд-разработчика. В будущем буду углубляться в webpack, всем спасибо