一、JS模块化打包
接着上面的示例,在src文件夹下新建module.js文件,内容如下:
const welcomeText = "Hello Webpack,今天是:"+new Date().toLocaleDateString();
//CommonJS规范中的模块输出语法
module.exports={
outputText:welcomeText
}
修改src文件夹下的index.js文件,通过CommonJS规范中的模块引入语法,引入module.js
//CommonJS规范中的模块引入语法
var module = require('./module.js');
document.write(module.outputText);
修改package.json文件中的scripts节点,增加start命令
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack"
},
这样我们就可以在命令终端输入npm run start或者npm start即可代替之前的npx webpack命令了。
打开dist下的index.js文件,可以观察到js的模块化引入多个js文件已经都被打包到一个js文件中
二、CSS打包
Webpack中提供了各种loader,它们是专门用来打包除js外其他格式文件的编译、提取、合并和打包等工作。
css文件的打包需要两个loader,分别是css-loader和style-loader
css-loader:用于加载css文件
style-loader:将打包后的css代码以<style>标签形式添加到页面头部
首先安装这两个loader,如下:
npm install --save-dev css-loader style-loader
安装完成后,修改webpack.config.js文件,增加模块规则引入
module: {
rules: [
{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
}
]
}
在src文件夹下创建css文件夹,并新增一个style.css
html{
font-size: 20px;
background-color:aqua;
}
在src/index.js文件中引入style.css样式文件
//CommonJS规范中的模块引入语法
var module = require('./module.js');
import './css/style.css';
document.write(module.outputText);
通过npm start打包后,运行浏览index.html,页面中文字的大小和背景颜色已经生效
为了不每次修改后,重新运行npm start命令,修改webpack.config.js文件增加watch命令,可实现自动化打包
module.exports = {
//需要被打包的js文件路径及文件名
entry: './src/index.js',
output: {
//打包输出的目标文件的绝对路径(其中__dirname为当前目录的绝对路径)
path: __dirname + '/dist',
//打包输出的js文件名及相对于dist目录所在路径
filename: 'index.js'
},
module: {
rules: [
{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
}
]
},
//监听修改,自动打包
watch: true
};
当watch配置为true后,通过npm start启动后,一直保持监听状态
此时我们如果修改js或者css,刷新页面就可以看到效果
三、图片打包
和css打包类似,图片打包需要使用到file-loader或者url-loader,两个包功能类似,主要区别在url-loader可以将文件大小小于某个值的图片转换成base64格式。
首先安装file-loader和url-loader,命令如下:
npm install --save-dev file-loader
npm install --save-dev url-loader
接着在webpack.cofig.js中增加相应配置,这里需要注意的是如果没有设置options选项,打包的图片名称会发生变化
说明:options中的name属性其实就是图片打包后的路径,其中包括图片名([name])和图片格式([ext])。
module: {
rules: [
{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
},
{
//正则表达式,表示图片文件
test: /\.(png|jpg|gif|svg)$/,
//针对图片文件使用的loader
loader: 'file-loader',
//选项,可以让打包后的图片保持原先的名称
options: {
name: 'images/[name].[ext]'
}
}
]
}
保存文件修改,可以发现dist下出现images文件夹,并且图片也拷贝过来了
由于我们使用的是Webpack5,所以先前配置的file-loader已经被弃用,所以会导致图片损坏,无法打开,页面背景也无法显示
在webpack.config.js中重新调整file-loader配置
module: {
rules: [{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
},
{ //正则表达式,表示图片文件
test: /\.(jpe?g|png|gif|svg)$/,
//针对图片文件使用的loader
use: [{
loader: "file-loader",
//选项,可以让打包后的图片保持原先的名称,并增加一些前缀
options: {
name: "images/[name]-[hash].[ext]",
esModule: false
}
}],
type: 'javascript/auto',
},
]
}
此时webpack会将src/images下的图片打包到dist/images文件夹下
刷新页面,可以发现图片已经应用到页面背景中
file-loader可以自动识别css代码中的图片路径,并将其打包到指定目录,如果在js文件中,需要我们将图片资源引入进来,让后将其图片路径添加到图片对象中
//CommonJS规范中的模块引入语法
var module = require('./module.js');
import './css/style.css';
var imgSrc = require('./images/bg.png');
var img = new Image();
img.src = imgSrc;
document.write(module.outputText);
//将图片添加到网页中
document.body.appendChild(img);
运行后js中使用的图片也能正常显示
下面我们介绍url-loader,前面说过它和file-loader功能类似,它主要可以对小于某个大小的图片进行base64格式的转化处理
修改webpack.config.js增加url-loader的相关配置
module.exports = {
//需要被打包的js文件路径及文件名
entry: './src/index.js',
output: {
//打包输出的目标文件的绝对路径(其中__dirname为当前目录的绝对路径)
path: __dirname + '/dist',
//打包输出的js文件名及相对于dist目录所在路径
filename: 'index.js'
},
module: {
rules: [
{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
},
{
//正则表达式,表示图片文件
test: /\.(jpe?g|png|gif|svg)$/,
//针对图片文件使用的loader
use: [{
loader: "url-loader",
//选项,可以让打包后的图片保持原先的名称,并增加一些前缀
options: {
name: "images/[name]-[hash].[ext]",
//204800B=204.8KB
limit: 2048000,
esModule: false
}
}],
type: 'javascript/auto',
}
]
},
//mode支持三种:development,production和none
mode: 'development',
//监听修改,自动打包
watch: true
};
limit属性的作用就是将小于204800B大小的图片转成base64格式,而大于这个大小的图片将会以file-loader的方式进行打包处理。
如果不写limit属性,那么url-loader就会默认将所有图片转成base64,可以看到图片作为base64格式内容写入到了index.js中
运行查看页面,可以看到图片格式是base64格式的
四、HTML打包
前面我们陆续介绍了利用webpack将js、css和图片打包到dist目录下,但是目前我们还是通过在dist目录下创建html页面,然后引入打包后的资源。
其实我们通过html-webpack-plugin插件也可以完成html打包
首先安装插件
npm install --save-dev html-webpack-plugin
在webpack.config.js中配置html-webpack-plugin
//引入html-webpack-plugin插件
const htmlWebpackPlugin = require('html-webpack-plugin');
module.exports = defineConfig({
publicPath: process.env.NODE_EVN === "production" ? "/sso-web/" : "./",
outputDir: process.env.outputDir, //使用定义的名字
lintOnSave: false, //关闭eslint提示
/* 是否保存时 lint 代码 */
// lintOnSave: process.env.NODE_ENV === "production",
/* 放置生成的静态文件目录(js css img) */
assetsDir: "static",
// publicPath: "./",
filenameHashing: false, // 打包的时候不使用hash值.因为我们有时间戳来确定项目的唯一性了.
configureWebpack: { //重点 清除浏览器缓存
output: { // 输出重构 打包编译后的js文件名称,添加时间戳.
filename: `js/js[name].${timeStamp}.js`,
chunkFilename: `js/chunk.[id].${timeStamp}.js`,
//更新一次代码 自动清理文件
clean: true
}
},
css: { //重点.
extract: { // 打包后css文件名称添加时间戳
filename: `css/[name].${timeStamp}.css`,
chunkFilename: `css/chunk.[id].${timeStamp}.css`,
}
},
module: {
rules: [{
//正则表达式,表示.css后缀的文件
test: /\.css$/,
//针对css文件使用的loader,有先后顺序,数组项越靠后越先执行(从下到上,从右到左)
use: ['style-loader', 'css-loader']
},
{
//正则表达式,表示图片文件
test: /\.(jpe?g|png|gif|svg)$/,
//针对图片文件使用的loader
use: [{
loader: "url-loader",
//选项,可以让打包后的图片保持原先的名称,并增加一些前缀
options: {
name: "images/[name]-[hash].[ext]",
//204800B=204.8KB
limit: 20480,
esModule: false
}
}],
type: 'javascript/auto',
}
]
},
//mode支持三种:development,production和none
mode: 'development',
//打包需要的各种插件
plugins: [
//打包HTML
new htmlWebpackPlugin({
//HTML模板路径
template: './src/index.html'
})
],
//监听修改,自动打包
watch: true,
}
HTML自身以及其他资源如CSS、图片等均无需手动添加,在打包结束后,所有资源均会自动添加至HTML文件相应位置并进入dist目录中
五、webpack-dev-server
前面我们介绍过监听项目更改,使用了配置
我们还可以直接给package.json中scripts添加相关配置,而无需更改webpack.config.js
Webpack还提供了一个比watch更方便的功能,它不仅可以实现自动打包,还具有自动打开浏览器和自动刷新页面的功能,它就是webpack-dev-server
首先安装插件
npm install --save-dev webpack-dev-server
在package.json中的scripts下添加相关配置
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"start": "webpack --watch",
"dev":"webpack-dev-server --open"
},
请点击
输入命令npm run dev,打包结束后浏览器会自动打开,并且正确显示打包后的页面。
通过webpack-dev-server打包后的代码并不会出现在dist目录中,而是直接创建了一个开发服务器,同时运行打包的代码。
Webpack打包通常分为两种模式:开发模式(development)和生产模式(production)
开发模式:开发时使用webpack-dev-server,代码自动打包、自动打开浏览器、自动刷新都可以实现自动化,提高开发效率。
生产模式:在代码最终上线时使用,只需要使用到最基本的打包功能,最终打包后的代码会进入到dist目录中,然后上传服务器即可