webpack现在可谓炙手可热,要是不懂,就难免让人觉得有点跟不上时代。
其实webpack只是一种工具,我们以使用为目的去学习它,就一点也不难哦,本篇文章让您在一个小时内上手webpack,没时间学习也可以先收藏哦。
webpack主要用于兼容性处理,代码预处理转换处理,压缩处理。
如转换ES6语法,转换JSX 指令等
CSS前缀补全/预处理器,代码压缩混淆,图片压缩等。
webpack的配置文件默认为webpack.config.js。
webpack --config命令可用于指定配置文件。
安装nodejs和npm,直接在nodejs官网下载安装包即可,npm作为nodejs附属包同时自动安装,无需另外安装。
使用nodejs安装包安装后可用命令行在cmd窗口查看安装版本。
首先,创建项目目录(空目录),使用命令行创建一个初始化的package.json。
向项目目录中安装webpack依赖,安装后目录中出现node_modules文件。
npm install webpack webpack-cli --save-dev
注意到上文命令行中包含后缀 --save-dev,含义如下。
主要区别在于打包后是否保留该依赖,webpack本身是打包工具,当然不需要保留啦。
安装成功后查看安装情况。
./node_modules/.bin/webpack -v
现在我们就可以使用webpack做项目了,首先做一个最简单的例子。
首先z在项目目录中创建配置文件webpack.config.js,
'use strict'
const path = require('path'); // 引入一个依赖
module.exports = {
entry: './src/index.js', // 入口
output: {
// 出口
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
mode: 'production'
};
在上面文件中,我们指定入口为’./src/index.js’,输出文件在dist文件夹中,名字为’bundle.js’。
翻译一下也就是,webpack会以’./src/index.js’为入口,将其与其所有的依赖打包为一个出口文件’bundle.js’放置在目录dist中。
我们首先创建文件’./src/index.js’与其依赖文件’./src/helloworld.js’。
在index.js中引入helloworld.js文件。
// './src/index.js'
import {
helloworld } from './helloworld';
document.write(helloworld());
// './src/helloworld.js'
export function helloworld() {
return 'hello webpack'
}
此时项目结构如下图。
./node_modules/.bin/webpack
项目目录下,出现了文件夹dist,其中含有bundle.js,与前面配置文件出口路径与名称对应。
可以看到,bundle.js文件是入口文件的整合版,运行效果与入口文件是相同的,只是少了依赖而已。
刚刚使用./node_modules/.bin/webpack
打包,未免繁琐,这里可以通过在package.json中对scripts添加配置的方式,设置快捷命令。
{
"name": "webpackTest",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"webpack": "^5.38.1",
"webpack-cli": "^4.7.0"
}
}
rm -rf dist // 删除之前的打包文件
npm run build // 打包文件 生成与刚刚相同的文件
刚刚的配置文件中见过,用于指定打包文件入口。
单入口情况下为字符串,多入口情况下为key-value对象。
刚刚的示例为单入口文件。
刚刚的配置文件中见过,用于指定编译后的文件输出。
// 单入口 单出口
module.exports = {
entry: './src/index.js', // 入口
output: {
// 出口
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
}
};
// 多入口 多出口
module.exports = {
entry: {
app: './src/app.js',
search: './src/search.js'
}
output: {
// 出口
path: path.join(__dirname, 'dist'),
filename: '[name].js'
}
};
可以看到,对于多入口出口配置,output中内容没有太大改变,其实是使用占位符[name]来实现文件动态命名的,打包后的dist目录中,有着对应入口文件的n个出口文件,名称与entry中的key值一致。
上面的配置文件中,打包结果为dist中出现两个文件,分别为app.js和search.js。
webpack原生支持js和json,通过loaders做其他文件类型的转换,如vue等,将其他文件类型转化为有效的模块,添加到依赖图中。
本身是一个函数,接受源文件作为参数,返回转换的结果。
常见loaders:
babel-loader | 转换ES6.ES7等 |
---|---|
css-loader | 支持.css文件的加载和解析 |
less-loader | 将less文件转换为css |
ts-loader | 将TS转换成JS |
file-loader | 进行图片 字体等的打包 |
raw-loader | 将文件以字符串的形式导入 |
thread-loader | 多进程打包JS和CSS |
用法
module.exports = {
module: {
rules: [
{
test:/\.txt$/,use:'raw-loader'} // 匹配规则 loader名称
]
}
}
插件,增强功能。作用于整个构建过程。
常用插件
用法
module.exports = {
plugins: [
new HtmlWebpackPlugin({
template: './src/index.html'})
// 创建html文件去承载输出的bundle
]
}
指定当前的构建环境是:production development none
默认为 production。
通过对mode的不同设置,可以使用webpack不同内置函数。
使用babel-loader完成。
npm i @babel/core @babel/preset-env babel-loader -D
在src同级目录下创建babel配置文件.babelrc,书写配置。
{
"presets": [
"@babel/preset-env"
]
}
修改webpack配置文件。
rules: [
{
test:/.js$/,
use: 'babel-loader'
}
]
配置完成后查看效果。
rm -rf dist
npm run build
此时已经解析成功了。
那如果是React语法如何解析呢。
安装babel-react。
npm i react react-dom @babel/preset-react -D
修改babel配置文件.babelrc。
{
"presets": [
"@babel/preset-env",
"@babel/preset-react"
]
}
书写一个简单的react-js文件,文件的含义是将一个模板放置到一个DOM节点上。
npm run build 构建即可查看效果。
将输出的JS文件放置到一个新建的html文件中,文件中含有对应的节点,就可以成功插入了。
解析CSS使用css-loader,将css转换为commonjs对象,使用style-loader,将样式通过
首先在项目中安装两个依赖。
npm i style-loader css-loader -D
在项目中创建css文件,写入一些样式,并在刚刚的react的js文件中引入使用。
在webpack配置文件中rules中添加loader。
module: {
...
rules: [
{
test: /.css$/,
use: [
'style-loader',
'css-loader'
]
}
]
}
再编译,生成的js文件,放置在html中就有对应效果了。
但是这时候还是没有单独的css文件的,要将css文件分离出来,要使用插件extract-text-webpack-plugin。
也可以使用mini-css-extract-plugin,都是用来抽离css样式,防止将样式打包在js中引起页面样式加载错乱的现象
extract-text-webpack-plugin 4.0的beta版本才支持webpack4.x 或者使用mini-css-extract-plugin
extract-text-webpack-plugin 默认版本 在webpack3.x可用
npm install extract-text-webpack-plugin --save-dev
var Ex = require('extract-text-webpack-plugin');
// ...省略
module: {
loaders: [{
test: /\.css/,
loader: Ex.extract('style-loader', 'css-loader','less-loader') // 单独打包出CSS,这里配置注意下
}]
},
plugins: [
new Ex("[name].css")
]
如果我们想要一个加载器数组,我们必须使用use,如果它只是一个加载器,那么我们必须使用loader。
安装less和less-loader依赖。
npm i less less-loader -D
将刚刚的css文件转换为less文件,之后在webpack中配置rules。
{
test: /.less$/,
use: [
'style-loader',
'css-loader',
'less-loader'
]
}
然后打包查看效果即可。
使用file-loader处理文件。
在src目录下放置图片logo.png,并在项目中引入使用。
npm i file-loader -D
在webpack配置文件中配置使用。
{
test: /.(png|jpg|gif|jpeg)$/,
use: 'file-loader'
}
打包即可。
与图片相同使用file-loader。
刚刚已经安装过依赖了,无需再安装,我们直接在css中引入和使用字体即可。
在webpack配置文件中添加配置。
{
test: /.(woff|woff2|eit|ttf|otf)$/,
use: 'file-loader'
}
然后打包编译即可。
文件监听是指在发现源码发生变化时,自动构建新的输出文件。
webpack开启监听模式,有两种方式。
首先我们使用第一种方式。
在package.json的scripts中添加配置watch。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"watch": "webpack --watch"
},
然后运行构建的时候,使用 npm run watch构建。
webpack会轮询判断文件的最后编辑时间是否变化,变化后会等待一段时间后执行。
刚刚说了第二种方式,也可在配置文件中配置。
webpack相关配置。
module.export = {
// 默认false 也就是不开启
watch: true,
// 只有开启监听模式时下面的设置才有效
watchOptions: {
// 忽略的文件 默认为空
ignored:/node_modules/,
// 监听后等待时候 默认300
aggregateTimeout:300,
// 轮询时间 默认1000
poll:1000
}
}
如此,当我在编辑了文件的时候,保存后webpack就会自动编译。
刚刚添加了自动构建功能,但是构建完成后需要我们手动刷新浏览器,浏览器的自动刷新在webpack中也有体现,就叫做热更新。
也就是webpack-dev-server。
安装该包依赖。
npm i webpack-dev-server -D
我们在在package.json的scripts中添加配置dev。
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack",
"watch": "webpack --watch",
"dev": "webpack-dev-server --open"
},
在webpack配置中引入并注册热更新插件,并进行配置。
// webpack.config.js
const webpack = require('webpack');
// webpack.config.js
plugins: [
new webpack.HotModuleReplacementPlugin()
],
devServer: {
contentBase: './dist',
hot:true
}
热更新的内容不会保存到磁盘,而是放置在内存中。
这时可能会有一个报错:
Cannot find module 'webpack-cli/bin/config-yargs'
是因为webpack-cli
的新版本对webpack-dev-server
版本的不兼容,之后降低webpack-cli
的版本为 "^3.3.12"
。
npm i [email protected] -D 就ok了。
webpack已经内置了uglifyjs-webpack-plugin插件进行JS压缩。
使用插件optimize-css-assets-webpack-plugin,同时使用cssnano。
安装依赖。
npm i optimize-css-assets-webpack-plugin
npm i cssnano -D
引用插件。
plugins: [
...,
new OptimizeCSSAssetsPlugin({
assetNameRegExp: /.css$/g,
cssProcessor: require('cssnano')
})
]
然后打包,打包成的就是压缩的css了。
设置插件html-webpack-plugin,设置压缩参数。
在html中新建html模板。
在webpack配置文件中引入html-webpack-plugin。
import HtmlWebpackPlugin = require(html-webpack-plugin)
在配置文件中配置插件。
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
...
plugins: [new HtmlWebpackPlugin()],
};
上面是最简单用法,这将会生成一个包含以下内容的 dist/index.html
文件。
如果你有多个 webpack 入口,他们都会在已生成 HTML 文件中的 标签内引入。
如果在 webpack 的输出中有任何 CSS 资源(例如,使用 MiniCssExtractPlugin 提取的 CSS),那么这些资源也会在 HTML 文件 元素中的
标签内引入。
也可以为这个插件传入一写参数,来指定入口html等值。