
了解如何使用Webpack生成JavaScript,图像,字体和样式,以及如何运行开发服务器。
如果您以前使用过Webpack 4,则与版本5有一些不同:
- “ webpack-dev-server”命令现在看起来像“ webpack-serve”
- 不再需要分别安装文件加载器,原始加载器和URL加载器,可以使用内置资产模块
- 不再支持Node.js的polyfills,因此,例如,如果您在流中遇到错误,则需要在Webpack设置中添加“ stream-browserify”包作为依赖项,并添加{stream:“ stream-browserify”}作为别名
什么是Webpack?
在大多数情况下,网站不再使用纯JavaScript编写而几乎没有JavaScript了-通常,它们仅使用JavaScript构建。因此,有必要构建,最小化和移植代码。这是webpack派上用场的地方。
Webpack是一个模块构建器。它用于打包供浏览器使用的代码。它使您可以利用Babel的最新JavaScript,或使用TypeScript并将其编译为跨浏览器的缩小代码。它还允许您将静态资源导入JavaScript。
对于开发人员,Webpack还提供了一个开发服务器,当保存文件时,该服务器可以即时更新模块和样式。诸如“ vue create”和“ react-create-app”之类的命令行工具在后台使用了webpack,但是您可以轻松地为这些框架创建自己的webpack设置。
Webpack也可以做很多其他事情,但是本文将介绍设置和使用它的基本知识。
安装
创建一个项目目录并对其进行初始化:
mkdir webpack-tutorial
cd !$
//
cd webpack-tutorial
yarn init -yp // "package.json"
//
npm init -y
安装webpack和webpack-cli作为开发依赖项:
yarn add -D webpack webpack-cli
//
npm i -D webpack webpack-cli
- webpack-模块和资源的收集器
- webpack-cli - webpack命令行界面
创建目录“ src”以存储应用程序文件。我将从创建一个简单的“ index.js”文件开始:
console.log(" !")
太好了,我们有一个Node.js项目,其中已安装了主要软件包和一个“ index.js”文件。让我们开始配置webpack。
基本设定
让我们开始配置收集器。在项目的根目录中创建文件“ webpack.config.js”。
入口点
首先,您需要定义应用程序的入口点,即 Webpack将编译哪些文件。在上面的示例中,我们将入口点定义为“ src / index.js”:
// webpack.config.js
const path = require('path')
module.exports = {
entry: {
main: path.resolve(__dirname, './src/index.js'),
},
}
出口点
出口点是Webpack编译的文件所在的目录。将出口点设置为“ dist”。“ [name]”前缀与src中的文件名匹配:
// webpack.config.js
module.exports = {
// ...
output: {
path: path.resolve(__dirname, './dist'),
filename: '[name].bundle.js',
},
}
准备用于构建项目的最小设置。将“ build”脚本添加到运行“ webpack”命令的“ package.json”文件中:
// package.json
"scripts": {
"build": "webpack"
}
启动webpack:
yarn build
//
npm run build
asset main.bundle.js 19 bytes [emitted] [minimized] (name: main)
./src/index.js 18 bytes [built] [code generated]
webpack 5.1.0 compiled successfully in 152 mss
在“ dist”目录中创建文件“ index.bundle.js”。文件没有更改,但是我们已经成功构建了项目。
外挂程式
插件 界面使webpack非常灵活。Webpack本身和第三方扩展都使用插件。几乎每个项目都使用某些插件。
基于HTML模板的插件
我们有一个现成的程序集,但是没有标记就没有用,它将标记集作为脚本加载。由于我们希望自动生成这样的HTML文件,因此我们使用html-webpack-plugin。
- html-webpack-plugin-基于模板创建HTML文件
安装插件:
yarn add -D html-webpack-plugin
在“ src”目录中创建一个“ template.html”文件。我们可以向模板添加变量和其他信息。添加变量“ title”,否则模板将看起来像是带有标识符为“ root”的容器的常规HTML文件:
<!-- src/template.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</html>
将“ plugins”属性添加到webpack设置中,在其中定义插件,输出文件的名称(index.html)和模板:
// webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
// ...
plugins: [
new HtmlWebpackPlugin({
title: 'webpack Boilerplate',
template: path.resolve(__dirname, './src/template.html'), //
filename: 'index.html', //
}),
],
}
我们开始组装。现在,“ dist”目录包含“ index.html”文件,其中包含脚本。凉!如果在浏览器中打开此文件,将看到消息“多么有趣!”。在控制台中。
让我们向DOM添加一些内容。让我们更改“ index.js”文件的内容,然后重新启动程序集。
// index.js
//
const heading = document.createElement('h1')
heading.textContent = ' !'
// DOM
const root = document.querySelector('#root')
root.append(heading)
转到“ dist”目录并启动服务器(为此,您需要全局安装http-server:yarn global添加http-server或npm i -g http-server)。
http-server
在打开的浏览器标签中,您应该看到标题为“多么有趣!”。还请注意文件大小的减小。
清洁用品
安装clean-webpack-plugin,它在每次构建项目时都会清理“ dist”目录。这使您可以自动删除不再需要的旧文件。
- clean-webpack-plugin-删除/清理项目构建目录
// webpack.config.js
const HtmlWebpackPlugin = require('html=webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
// ...
plugins: [
// ...
new CleanWebpackPlugin(),
],
}
模块和装载机
Webpack使用加载程序来解析模块加载的文件。这些可以是JavaScript文件,图像或样式之类的静态资源,以及TypeScript和Babel之类的编译器。Webpack 5有几个内置的资源加载器。
我们的项目有一个HTML文件,该文件加载了一些脚本,但没有执行其他操作。让我们考虑一下我们想要从收藏家那里得到什么?
- 将最新的JavaScript功能编译为与所有或大多数浏览器兼容的代码
- 导入样式并将SCSS转换为CSS
- 导入图像和字体
- 设置React或Vue(可选)
首先,让我们设置Babel来编译JavaScript。
Babel(JavaScript)
Babel是当今启用未来JavaScript的工具。
我们将定义一个规则,即将使用babel-loader转译项目中的所有js文件(node_modules目录中包含的文件除外)。Babel需要几个依赖项才能工作:
- babel- loader-使用Babel和webpack编译文件
- @ babel / core-将ES2015 +移植到向后兼容的JavaScript
- @ babel /预设环境-有用的Babel默认预设
- @ babel / plugins-proposal-class-properties-一个自定义Babel配置的示例(在类的主体中而不是在其构造函数中设置实例属性)
yarn add -D babel-loader @babel/core @babel/preset-env @babel/babel-plugin-proposal-class-properties
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
// JavaScript
{
test: /\.js$/,
exclude: /node_modules/,
use: ['babel-loader'],
},
],
}
}
如果要设置TypeScript项目,则对于需要翻译的所有JavaScript文件,都应使用typescript-loader而不是babel-loader。您正在检查带有“ ts”扩展名的文件并使用ts-loader。
这样就建立了Babel,但是该插件还不存在。您可以通过在index.js顶部添加以下代码来验证这一点:
// index.js
//
class Game {
name = 'Violin Charades'
}
const myGame = new Game()
//
const p = document.createElement('p')
p.textContent = `I like ${myGame.game}.`
//
const heading = document.createElement('h1')
heading.textContent = ' !'
// DOM
const root = document.querySelector('#root')
root.append(heading, p)
ERROR in ./src/index.js
Module build failed (from ./node_modules/babel-loader/lib/index.js):
SyntaxError: /Users/you/webpack-tutorial/src/index.js: Support for the experimental syntax 'classProperties' isn't currently enabled (3:8):
1 | // Create a class property without a constructor
2 | class Game {
> 3 | name = 'Violin Charades'
| ^
4 | }
要解决此问题,请在项目的根目录中创建一个“ .babelrc”文件:
// .babelrc
{
"presets": ["@babel/preset-env"],
"plugins": ["@babel/plugin-proposal-class-properties"]
}
我们从纱线构建开始构建。现在一切正常。
图片
我们想将图像导入到JavaScript文件中,但是JavaScript无法做到这一点。为了验证这一点,我们创建一个目录“ src / images”,在其中放置一个图像,然后尝试将其导入文件“ index.js”:
// index.js
import example from './images/example.png'
// ...
开始构建时将引发异常:
ERROR in ./src/images/example.png 1:0
Module parse failed: Unexpected character ' ' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
如前所述,webpack具有一些用于处理静态文件的内置下载器。对于图像,请使用“资产/资源”类型。请注意,我们在谈论的是类型(type),而不是关于加载器(loader):
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
//
{
test: /\.(?:ico|gif|png|jpg|jpeg)$/i,
type: 'asset/resource',
},
],
},
}
新文件出现在“ dist”目录中。
字体和其他嵌入式数据
该webpack还具有一个内置模块来处理一些嵌入式数据,例如字体和SVG。为此,只需指定类型“资产/内联”即可:
// index.js
import example from './images/example.svg'
// ...
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
// SVG
{
test: /\.(woff(2)?|eot|ttf|otf|svg|)$/,
type: 'asset/inline',
},
],
},
}
款式
使用样式加载器是在脚本中使用“ import'file.css”之类的字符串的先决条件。
许多人使用CSS-in-JS,样式化的组件以及其他允许JavaScript样式化的工具。
有时我们可以限制自己加载一个CSS文件。但是也许您想使用PostCSS,它可以在浏览器中提供最新的CSS功能。还是要使用Sass预处理程序。
我想使用所有这三个-用Sass编写代码,用PostCSS处理它,然后编译成CSS。
- sass- loader-加载SCSS并将其编译为CSS
- node-sass-节点Sass
- postcss- loader-使用PostCSS进行CSS处理
- postcss-preset- env-有用的PostCSS设置
- css-loader-加载样式
- 样式加载器-将样式应用于DOM元素
yarn add -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass
与Babel一样,PostCSS需要一个单独的配置文件:
// postcss.config.js
module.exports = {
plugins: {
'post-css-preset-env': {
browsers: 'last 2 versions',
},
},
}
为了测试命名工具的功能,让我们创建一个文件“ src / styles / main.scss”,其中包含Sass变量以及使用PostCSS(lch)的示例:
// src/styles/main.css
$font-size: 1rem;
$font-color: lch(53 105 40);
html {
font-size: $font-size;
color: $font-color;
}
我们将此文件导入index.js并添加4个加载程序。webpack从右到左使用加载器,因此最后一个应该是sass-loader,然后是PostCSS,然后是CSS,最后是style-loader,后者将已编译的样式应用于DOM元素:
// index.js
import './styles/main.css'
// ...
// webpack.config.js
module.exports = {
// ...
module: {
rules: [
// CSS, PostCSS, Sass
{
test: /\.(scss|css)$/,
use: ['style-loader', 'css-loader', 'postcss-loader', 'sass-loader'],
},
],
},
}
构建完成后,您会注意到Sass和PostCSS已应用于DOM。
请注意,我们已经设置了开发模式的首选项。对于生产,请使用MiniCssExtractPlugin而不是style-loader,后者会导出缩小的CSS。
发展
每次重新构建项目时,键入纱线构建(npm run build)可能是乏味的。项目越大,构建所需的时间就越长。因此,您需要具有两个webpack配置文件:
- 生产设置,包括最小化,优化和删除所有资源图(源图)
- 开发设置包括服务器启动,每次更改更新和资源映射
开发模式可以期望将所需的信息存储在内存中,而不是创建“ dist”目录。
为此,您需要安装webpack-dev-server。
- webpack-dev-server是开发服务器
yarn add -D webpack-dev-server
为了演示如何使用服务器进行开发,我们可以在“ webpack.config.js”文件中定义适当的设置。实际上,最好有两个配置文件,一个配置文件为生产模式,另一个配置文件为开发模式。在为您专门准备的webpack 5样板中,我使用webpack-merge在单个文件中获取基本设置,并且特殊要求包含在“ webpack.prod.js”和“ webpack.dev.js”文件中。
// webpack.config.js
const webpack = require('webpack')
module.exports = {
// ...
mode: 'development',
devServer: {
historyApiFallback: true,
contentBase: path.resolve(__dirname, './dist'),
open: true,
compress: true,
hot: true,
port: 8080,
},
plugins: [
// ...
//
new webpack.HotModuleReplacement(),
],
}
我们添加了模式:开发和“ devServer”属性。此属性包含几个标准设置-端口号(8080),自动打开浏览器,使用hot-module-replacement,这需要webpack.HotModuleReplacement()。这将允许模块更新而无需重新加载整个页面,即 如果个别样式发生更改,则仅对其进行更新,您无需重新加载JavaScript,从而大大加快了开发速度。
要启动服务器,请使用“ webpack serve”命令:
// package.json
"scripts": {
"start": "webpack serve"
}
yarn start
运行此命令后,浏览器将在本地主机上打开:8080。现在,您可以修改Sass和JavaScript,它们将即时更新。
结论
我希望本文能帮助您开始使用webpack。为了更轻松地解决您的日常任务,我开发了一个Webpack 5样板,其中包含Babel,Sass,PostCss,用于生产的优化和用于开发的服务器。以它为基础,您可以轻松地将Webpack配置为与React,Vue或TypeScript一起使用。