webpack开发一个js库(深入理解JavaScript打包工具WebPack)
webpack开发一个js库(深入理解JavaScript打包工具WebPack)阅读本文你将有如下收获:l Nodejs 和npm 的安装部署l 了解JavaScript 语言l 理解DOMl 熟悉JavaScript ES6 语法及特征
对我来说,webpack曾经是一个令人头痛的内容。我觉得使用像create -React-app 这样的东西来设置一个项目是安全的,但是如果可能的话,我避免了webpack,因为它看起来很复杂和令人困惑。
如果您不喜欢从头开始设置网页包以用于巴别,TypeScript,sass,React或Vue,或者不知道为什么您可能想要使用网络包,那么这是最适合您的文章。像所有事情一样,一旦你深入研究并学习它,你就会意识到它并不那么可怕,只有几个主要概念需要学习设置。
读者的知识储备要求:
l 基本熟悉HTML&CSS
l 了解JavaScript 语言
l 理解DOM
l 熟悉JavaScript ES6 语法及特征
l Nodejs 和npm 的安装部署
阅读本文你将有如下收获:
- 了解什么是 web 包以及您可能想要使用它的原因
- 使用webpack 启动开发服务development server
- 使用 web 包设置生产构建流程
在大多数情况下,网站不再只是用普通的HTML编写,带有一些可选的JavaScript - 它们通常完全由JavaScript构建。因此,我们必须将代码捆绑,缩小和转译成所有浏览器都能理解的内容,这就是webpack的用武之地。
webpack是一个模块打包器。它为浏览器整齐地打包了所有代码。它允许您使用babel编写最新的JavaScript或使用TypeScript,并将其编译成跨浏览器兼容且整齐地缩小的内容。它还允许您将静态资产导入到 JavaScript 中。
对于开发,webpack还提供了一个开发服务器,可以在您保存时动态更新模块和样式。vue ceate和create-react-app依赖于底层的 webpack,但你可以很容易地为它们设置自己的 web pack配置。
webpack可以做更多的事情,但本文将帮助您熟悉这些概念并进行设置。
安装 webpack首先,为项目创建一个目录,然后启动 Node 项目。我称之为webpack-demo。
mkdir webpack-demo
cd webpack-demo
npm init -y # creates a default package.json
首先,安装webpack和webpack-cli。
npm i -D webpack webpack-cli
webpack: 模块和静态资源打包器
webpack-cli: webpack的命令行
基本配置 Basic configuration在webpack-demo文件下创建 webpack.config.js 文件。
Entry 配置webpack.config.js
const path = require('path')
module.exports = {
entry: {
main: path.resolve(__dirname './src/index.js')
}
}
Output 配置
输出是打包后文件的目录。我们将它输出到 dist 文件夹中,这是生成生产代码的地方。输出中的 [name] 将是主条目对象中指定的 [name]。
webpack.config.js
module.exports = {
/* ... */
output: {
path: path.resolve(__dirname './dist')
filename: '[name].bundle.js'
}
}
现在,我们拥有构建捆绑包所需的最小配置。在package.json 中,我们可以创建一个运行 webpack 命令的build脚本。
package.json
"scripts": {
"build": "webpack"
}
然后执行build 打包文件
npm run build
在dist 文件夹下看到main.bundle.js
Plugins 插件webpack有一个插件plugin配置,使它变得灵活。内部 webpack 代码和第三方扩展使用插件。有几个主要的,几乎每个webpack项目都会使用。
HTML template file- html-webpack-plugin - 从模板文件生成 html文件
安装插件:
npm i -D html-webpack-plugin
在 src 文件夹中创建一个template.html文件。我们可以在模板中包含变量和其他自定义信息。我们将添加一个自定义标题,否则它将看起来像一个带有根 div 的常规 HTML 文件。
src/template.html
<!DOCTYPE html>
<html lang="en">
<head>
<title><%= htmlWebpackPlugin.options.title %></title>
</head>
<body>
<div id="root"></div>
</body>
</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') // template file filename: 'index.html' // output file }) ] }
运行build 后
dist 文件夹出现index.html
Clean 插件clean-webpack-plugin ,可以清理dist 目录下所有内容
webpack.config.js
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
const { CleanWebpackPlugin } = require('clean-webpack-plugin')
module.exports = {
/* ... */
plugins: [
/* ... */
new CleanWebpackPlugin() ]
}
Modules and Loaders 模块管理和加载器
webpack使用加载器来预处理通过模块加载的文件。这可能是 JavaScript 文件、静态资产(如图像和 CSS 样式)以及编译器(如类型脚本和识别样式)。webpack 5 也有一些内置的资产加载器。
在你的项目中,你有一个HTML文件,可以加载并引入一些JavaScript,但它实际上仍然没有做任何事情。我们希望这个webpack配置做的主要事情是什么?
- 编译最新版本的JavaScript 代码,兼容目标浏览器
- 引入样式文件并编译SCSS 为CSS
- 引入图像和字体
- 配置 React 或 Vue
Babel 允许我们使用最新版本的JavaScript标准。
- babel-loader - 使用Babel .
- @babel/core - 将ES2015 JavaScript 代码兼容旧浏览器
- @babel/preset-env - 默认配置
- @babel/plugin-proposal-class-properties -建议配置
npm i -D babel-loader @babel/core @babel/preset-env @babel/preset-env @babel/plugin-proposal-class-properties
webpack.config.js
module.exports = {
/* ... */
module: { rules: [ // JavaScript { test: /\.js$/ exclude: /node_modules/ use: ['babel-loader'] } ] } }
src/index.js
// Create a class property without a constructorclass Game { name = 'Violin Charades'}const myGame = new Game()// Create paragraph nodeconst p = document.createElement('p')p.textContent = `I like ${myGame.name}.`
// Create heading node
const heading = document.createElement('h1')
heading.textContent = 'Interesting!'
// Append SVG and heading nodes to the DOM
const app = document.querySelector('#root')
app.append(heading p)
run build将报错
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"]
}
npm run build 将成功打包
Images 插件如代码引入图像
src/index.js
import example from './images/example.png'
/* ... */
直接允许 build 会报错
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.config.js
module.exports = {
/* ... */
module: {
rules: [
// Images { test: /\.(?:ico|gif|png|jpg|jpeg)$/i type: 'asset/resource' } ]
}
}
字体或其它内置资源 Fonts and inline
如引入字体或内置svg 等
src/index.js
import example from './images/example.svg'
/* ... */
webpack.config.js
module.exports = {
/* ... */
module: {
rules: [
// Fonts and SVGs { test: /\.(woff(2)?|eot|ttf|otf|svg|)$/ type: 'asset/inline' } ]
}
}
样式 Styles
- sass-loader - sass 加载器
- postcss-loader - Process CSS with PostCSSpostcss-preset-env - Sensible defaults for PostCSS
- css-loader - CSS加载器
- style-loader - 嵌入CSS
npm i -D sass-loader postcss-loader css-loader style-loader postcss-preset-env node-sass
postcss.config.js
module.exports = {
plugins: {
'postcss-preset-env': {
browsers: 'last 2 versions'
}
}
}
举例;
src/styles/main.scss
使用scss 变量
src/styles/main.scss
$font-size: 1rem;
$font-color: lch(53 105 40);
html {
font-size: $font-size;
color: $font-color;
}
src/index.js
import './styles/main.scss'
/* ... */
webpack.config.js
module.exports = {
/* ... */
module: {
rules: [
// CSS PostCSS and Sass { test: /\.(scss|css)$/ use: ['style-loader' 'css-loader' 'postcss-loader' 'sass-loader'] } ]
}
}
Development 开发服务
每次进行更新时运行 npm run build 都很繁琐。网站越大,构建所需的时间就越长。您需要为 webpack 设置两个配置:
- 生产配置,最小化,优化和删除所有源映射
- 一个开发配置,在服务器中运行webpack,每次更改都会更新,并具有源映射
安装 webpack-dev-server 开发服务
npm i -D webpack-dev-server
配置两个文件
生产:webpack.prod.js
开发: webpack.dev.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: [
/* ... */
// Only update what has changed on hot reload
new webpack.HotModuleReplacementPlugin()
]
})
通过设置mode: development
并创建devServer
然后在packag.json 增加启动开发服务脚本
package.json
"scripts": {
"start": "webpack serve"
}
npm start
运行此命令时,浏览器中将自动弹出指向 localhost:8080 的链接。现在,您可以更新 Sass 和 JavaScript,并观看它即时更新。