предисловие
Прошло некоторое время с момента выпуска webpack4.В процессе практики я обнаружил, что многие конфигурации проекта нормально работают под webpack3, но он вылетает сразу после обновления до webpack4.Если вы хотите, чтобы webpack4 работал нормально, многие плагины также должны быть обновился до новой версии. Ниже приведен учебный пример моей конфигурации с использованием webpack4, который включает в себя общие элементы конфигурации для ежедневной разработки, такие как конфигурация файла с несколькими записями, настройка файла шаблона, контроль номера версии, разделение js и css, автоматическое добавление префикса css, scss к css, изображения и обработка файлов шрифтов, JS-синтаксис и API, скомпилированные babel, и т. д.
номер версии
Когда мы модифицируем код, нам нужно переупаковать файл.В настоящее время, чтобы избежать кэширования браузера, нам часто нужно добавить номер версии к файлу.
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
plugins: [
new HtmlWebpackPlugin({
inject:'body', // 插入位置
favicon: './favicon.ico', // icon图标
title: 'webpack learn', // 生成的html文件的标题
filename: 'index.html', // 生成的html文件名称
minify:{
removeComments: false, // 删除注释
collapseWhitespace: false // 删除空格
}
})
]
}
упакованный код
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack learn</title>
<link rel="shortcut icon" href="favicon.ico">
</head>
<body>
<script type="text/javascript" src="main.js?f8f60ca3f6ee44382620"></script></body>
</html>
Плагин html-webpack-plugin создаст файл с именем index.html и заголовкомwebpack learn
файл и автоматически вставит упакованный файл в html. Если этот плагин не настроен, значение имени файла по умолчанию равноindex.html
, заголовок по умолчаниюWebpack APP
inject указывает позицию вставки, по умолчаниюbody
, необязательное значениеhead
favicon означает, что вы можете добавить значок значка
minify означает, что для сжатых файлов значения по умолчанию для removeComments и CollapWhitespace равны false.
файл шаблона
Плагин html-webpack-plugin может использовать файлы шаблонов, чтобы мы могли настроить html-файл, а затем позволить плагину автоматически вставить упакованный файл в файл шаблона.
файл шаблона tmp/tmp.html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>template file</title>
<body>
<div>hello template</div>
</html>
Элементы конфигурации плагина
plugins: [
new HtmlWebpackPlugin({
filename: 'index.html',
template: './tmp/tmp.html'
})
]
index.html создается после упаковки
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>template file</title>
<body>
<div>hello template</div>
</html>
<script type="text/javascript" src="main.js?b321307e65d6b0fbee0b"></script>
несколько страниц
Для нескольких страниц это обычно соответствует нескольким файлам записей, а разные выходные данные html-страниц соответствуют разным файлам записей Плагин html-webpack-plugin поддерживает настройку нескольких страниц. На нескольких страницах необходимо настроить фрагменты и excludeChunks, фрагменты представляют собой включенные файлы записей, excludeChunks представляют файлы входов, которые необходимо исключить.
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: {
a: './src/main-a.js',
b: './src/main-b.js',
c: './src/main-c.js'
},
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
plugins: [
new HtmlWebpackPlugin({
filename: 'a.html',
template: './tmp/tmp.html',
chunks: ['a'] // 加载a对应的打包文件
}),
new HtmlWebpackPlugin({
filename: 'b.html',
template: './tmp/tmp.html',
chunks: ['b'] // // 加载b对应的打包文件
}),
new HtmlWebpackPlugin({
filename: 'c.html',
template: './tmp/tmp.html',
excludeChunks: ['a', 'b'] // 加载非a、b对应的打包文件
})
]
}
результат операции
<!-- a.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack learn</title>
<body>
<div>hello template</div>
</html>
<script type="text/javascript" src="a.js?82a9a04389852053c167"></script>
<!-- b.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack learn</title>
<body>
<div>hello template</div>
</html>
<script type="text/javascript" src="b.js?82a9a04389852053c167"></script>
<!-- c.html -->
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>webpack learn</title>
<body>
<div>hello template</div>
</html>
<script type="text/javascript" src="c.js?82a9a04389852053c167"></script>
в линию
Помимо импорта файла записи в качестве ссылки, его также можно встроить в страницу. Плагин html-webpack-inline-source-plugin предназначен для обработки встраивания входных файлов.
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackInlineSourcePlugin = require('html-webpack-inline-source-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
plugins: [
new HtmlWebpackPlugin({
inlineSource: '.(js|css)$' // 所有的js和css文件内联引入
}),
new HtmlWebpackInlineSourcePlugin()
]
}
babel
Babel может преобразовать последний стандартный код es в код es5.Во-первых, вам нужно установить базовую программу babel-core и загрузчик babel.
npm i babel-loader babel-core -D
Поскольку ES выпускает новую версию каждый год, при конвертации вам нужно выбрать, из какого стандарта конвертировать.Существуют различные стандарты es2015, es2016, es2017, last, env и т. д.
Стандарт babel-preset-env используется чаще всего, babel-preset-env аналогичен babel-preset-latest (или babel-preset-es2015, babel-preset-es2016 и babel-preset-es2017 без каких-либо параметров конфигурации). вместе) ведут себя точно так же
npm i babel-preset-env -D
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
module: {
rules:[{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
cacheDirectory: true
}
}
}]
}
}
Представление исключения, настроенное в атрибуте rulesnode_modules
Папкам не нужен babel для конвертации. Вы также можете настроить параметр включения, напримерinclude: path.resolve(__dirname, 'src')
, указывая, что нужно преобразовать только файлы в папке src
Значение параметра cacheDirectory по умолчанию равно false. Установка его в значение true приведет к кэшированию результата выполнения загрузчика и ускорению компиляции.
Преобразование API
Babel по умолчанию преобразует только синтаксис JavaScript. Для новых API, таких как Iterator, Generator, Set, Maps, Proxy, Reflect, Symbol, Promise и т. д., преобразование не производится. Если вам нужно преобразовать API, вам нужно использовать babel-polyfill, babel-polyfill — это глобальная прокладка
npm i babel-polyfill -D
Входной файл представляет babel-polyfill
// main.js
import 'babel-polyfill';
let set = new Set([1,2,3]);
babel-polyfill — это глобальная оболочка, а локальная оболочка babel-plugin-transform-runtime чаще используется в разработке, поскольку она может уменьшить размер пакета.
npm i babel-plugin-transform-runtime babel-runtime -D
var webpack = require('webpack');
var path = require('path');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
module: {
rules:[{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: ['env'],
cacheDirectory: true,
plugins: ['transform-runtime']
}
}
}]
}
}
CSS
css-loader и style-loader используются для обработки css, css-loader используется для чтения и загрузки css-файлов, а style-loader вставляет их на страницу
// main.js
require('./assets/styles/cssdemo.css');
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
module: {
rules:[{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}]
},
plugins: [
new HtmlWebpackPlugin({})
]
}
автоматический префикс
Из-за различной совместимости основных браузеров с CSS некоторые функции CSS должны иметь префикс браузера для правильной работы. postcss-loader может помочь нам автоматически завершить работу с префиксом.
npm i postcss-loader autoprefixer postcss-import -D
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', {
loader: 'css-loader',
options: { importLoaders: 1 }
},
{
loader: 'postcss-loader',
options: {
plugins: [
require('postcss-import'), // 解决css中import其他css
require('autoprefixer')
]
}
}
]
}]
}
sass
Необходимо установить sass-loader и node-sass.
npm i sass-loader node-sass -D
module: {
rules: [{
test: /\.scss$/,
use: ['style-loader','css-loader',
{
loader: 'postcss-loader',
options: { plugins: [require('autoprefixer')] }
},
'sass-loader'
]
}]
}
отдельный css
По умолчанию CSS будет упакован в входной JS-файл. Если вам нужно отделить CSS, вам нужно использовать плагин extract-text-webpack-plugin.
npm i extract-text-webpack-plugin@next -D
var webpack = require('webpack');
var path = require('path');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = {
entry: './src/main.js',
output: {
path: path.join(__dirname, 'dist'),
filename: '[name].js?[hash]'
},
module: {
rules: [{
test: /\.scss$/,
use: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: ['css-loader',
{
loader: 'postcss-loader',
options: { plugins: [require('autoprefixer')] }
},
'sass-loader'
]
})
}]
},
plugins: [
new HtmlWebpackPlugin({}),
new ExtractTextPlugin('main.css')
]
}
Ресурсы изображений
Когда веб-пакет обрабатывает такие ресурсы, как изображения, шрифты, музыка, видео и т. д., вам необходимо установить загрузчик файлов.
npm i file-loader -D
// main.js
require('./assets/styles/cssdemo.css');
/* cssdemo.css */
body {
background: url('../images/dog.jpg') no-repeat;
}
h1 {
color: red;
}
module: {
rules: [{
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.(eot|svg|ttf|woff|woff2)(\?\S*)?$/,
loader: 'file-loader'
},
{
test: /\.(png|jpe?g|gif|svg)(\?\S*)?$/,
loader: 'file-loader',
query: {
name: '[name].[ext]?[hash]'
}
}
]
}
Если в html шаблоне картинка импортируется через тег img, нужно использовать${require('')}
оберните относительный путь один раз
<img src="${require('../src/images/dog.jpg')}" alt="">
сторонняя библиотека
Например, если мы установили jQuery через npm, нам нужно только использовать плагин Provide-Plugin для автоматической загрузки модуля без необходимости импортировать или запрашивать везде.
npm i provide-plugin -D
var ProvidePlugin = require('provide-plugin');
plugins: [
new webpack.ProvidePlugin({
$: 'jquery',
jQuery: 'jquery'
})
]
использовать в проекте
console.log($('#box'), jQuery('#box'))
Если вы сохраняете jQuery локально, вы можете ссылаться на него, установив псевдоним
resolve:{
alias:{
jQuery$: path.resolve(__dirname,'src/libs/jquery.min.js')
}
}
Практичная конфигурация
Наконец, основываясь на всех введениях выше, соберите все конфигурации вместе. Так как кода много, я не буду его здесь расширять, выкладываю пример кода на GitHub.