- Webpack本身只能处理JavaScript模块,如果要处理其他类型的文件,就需要结合插件来使用,这写插件在Webpack中被称为 Loader(加载器)来进行转换
- Loader可以理解为模块和资源的转换器,它本身是一个函数,参数接受的是源文件,返回值是转换后的结果
- 这样,我们就可以通过require或import 来加载任何类型的模块或文件,比如CSS ,图片
1 打包CSS资源文件
创建 demo3项目
1 安装style-loader和css-loader依赖
首先安装相关Loader插件:
-
css-loader 是将css装载到javascript
-
style-loader 是让javascript认识css
npm install --save-dev style-loader css-loader
修改 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<script src="./dist/bundle.js"></script>
<p id="title">aaabbbb</p>
<div id="box1"></div>
</body>
</html>
2 .修改 webpack.config.js
//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");
// 导出一个webpack具有特殊属性配置的对象
module.exports = {
mode: "development" ,
//入口
//入口模块文件路径
entry: "./src/main.js" ,
//出口是对象
output: {
//path是一个绝对路径,__dirname 是当前js的绝对路径
path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
filename : "bundle.js" //打包的结果文件名
},module:{ //模块
rules: [ // 规则
{
test : /\.css$/ , //正则表达式,匹配 .css 文件资源
use: [
"style-loader",
"css-loader"
]
}
]
}
}
package.json
{
"name": "demo3",
"version": "1.0.0",
"main": "webpack.config.js",
"scripts": {
"build": "webpack --config ./webpack.config.js"
},
"author": "",
"license": "ISC",
"devDependencies": {
"css-loader": "^3.4.2",
"style-loader": "^1.1.3"
},
"dependencies": {},
"description": ""
}
3 在src文件加创建css文件夹,css文件夹下创建 style.css
body{
background: red;
}
#title {
color: blue;
}
4 在main.js中引入style.css
// 模块方式导入css,最终会打成js,打包在 bundle.js中
import './css/style.css'
5 重新打包编译
npm run build
打包后,查看bundle.js ,发现已经将css样式以js方式引入了
6 访问index.html 发现背景已经变成红色了。
原理: F12查看 index.html源码后,其实是将css文件内容转成一个javascript模块,然后在运行javascript时,会将样式动态使用<style>
标签,放在<head>
标签下
2 打包 Images资源
2.1 打包 Images步骤
1 安装 file-loader 依赖
npm install --save-dev file-loader
2 修改webpack.config.js
//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");
// 导出一个webpack具有特殊属性配置的对象
module.exports = {
mode: "development" ,
//入口
//入口模块文件路径
entry: "./src/main.js" ,
//出口是对象
output: {
//path是一个绝对路径,__dirname 是当前js的绝对路径
path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
filename : "bundle.js" //打包的结果文件名
},module:{ //模块
rules: [ // 规则
{
test : /\.css$/ , //正则表达式,匹配 .css 文件资源
use: [
"style-loader",
"css-loader"
]
} ,
{
test : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 .css 文件资源
use: [
"file-loader"
]
}
]
}
}
3, 修改 style.css
body{
background: red;
background-image : url(../images/img.jpg);
}
#box1{
width: 500px;
height: 500px;
background-image : url(../images/img.jpg);
background-repeat: no-repeat;
background-size: 100% 100%;
}
在src目录下新建images
文件夹,把图片img.jpg放到这个目录下。
4 打包编译
npm run build
5 访问跟目录下的index.html,背景图并未显示出来
6 问题:
如果直接访问根目录下的index,那么图片资源路径就无法访问到 解决方案: 把index.html放到 dist目录中,但是dist是打包编译后的结果,而非源码,所以把index.html放到dist就不合适,而且如果我们一旦把打包的结果文件名 bundle.js改了之后,则index.html也需要手动修改,综合以上遇到的问题,可以使用一个插件 html-webpack-plugin来解决。
2.2 使用HtmlWebpackPlugin插件
作用: 解决文件路径问题
- 将index.html打包到bundle.js所在目录
- 同时也会在index.html中自动的将
<script>
引入 bundle.js
1 安装插件
npm install --save-dev html-webpack-plugin
2 修改webpack.config.js
//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");
//引入插件
const HtmlwebpackPlugin = require("html-webpack-plugin")
// 导出一个webpack具有特殊属性配置的对象
module.exports = {
mode: "development" ,
//入口
//入口模块文件路径
entry: "./src/main.js" ,
//出口是对象
output: {
//path是一个绝对路径,__dirname 是当前js的绝对路径
path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
filename : "bundle.js" //打包的结果文件名
},module:{ //模块
rules: [ // 规则
{
test : /\.css$/ , //正则表达式,匹配 .css 文件资源
use: [
"style-loader",
"css-loader"
]
} ,
{
test : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 .css 文件资源
use: [
"file-loader"
]
}
]
},
//配置插件
plugins: [
new HtmlwebpackPlugin({
//此插件作用是将 index.html打包到bundle.js所在目录中
//同时会在 index.html中自动的在<script>引入 bundle.js
template : "./index.html"
})
]
}
注意:webpack项目中报错:Error: Cannot find module 'webpack/lib/node/NodeTemplatePlugin' 的解决 办法
如果package.json里没有本地安装webpack. 直接本地安装: npm install webpack --save-dev
3 修改 index.html, 模拟vue页面
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<!-- <script src="./dist/bundle.js"></script> -->
<!-- 使用了HtmlwebpackPlugin插件后悔自动引入bundle.js-->
<div id="app">abc</div>
</body>
</html>
4 重新打包
npm run build
运行后会发现dist目录下多了一个index.html,并且文件中自动引入了bundle.js
5 运行dist/index.html文件,背景图正常显示了,不要运行了根目录下的 index.html
html引入图片资源
1 安装 url-loader
, html-loader
依赖
npm install --save-dev url-loader
npm install --save-dev html-loader
2 修改 index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<p id="title">aaabbbb</p>
<div id="box1"></div>
<img src="./src/images/img.jpg">
</body>
</html>
2 webpack.conf.js
//引用Node.js中的path模块,处理文件路径的小工具
const path = require("path");
//引入插件
const HtmlwebpackPlugin = require("html-webpack-plugin")
// 导出一个webpack具有特殊属性配置的对象
module.exports = {
mode : "development" ,
//入口
//入口模块文件路径
entry: './src/main.js' ,
//出口是对象
output: {
//path是一个绝对路径,__dirname 是当前js的绝对路径
path: path.join(__dirname , "./dist/"), //打包的结果文件存储目录
filename : "bundle.js" //打包的结果文件名
},module:{ //模块
rules: [ // 规则
{
test : /\.css$/ , //正则表达式,匹配 .css 文件资源
use: [
"style-loader",
"css-loader"
]
} ,
{
test : /\.(png|svg|jpg|gif)$/ , //正则表达式,匹配 文件资源
loader: "url-loader"
,
options:{
// 图片大小小于400KB,就会被base64处理,优点: 简绍请求数量,减轻服务器压力
limit : 400 * 1024,
//因为url-loader默认使用 es6模块化解析,而html-loader引入tupianshi commonjs
// 解析式会出现问题: [object Module]
// 解决: 关闭 url-loader的es6模块化,使用commonjs解析
esModule: false ,
// 给图片进行重命名
// [hash:10].[ext] 取图片的hash值的前10位
name : '[hash:10].[ext]'
}
} ,
{
test : /\.html$/ ,
//处理html文件的img图片,负责引入图片,从而能被打包处理
loader: "html-loader"
}
]
},
//配置插件
plugins: [
new HtmlwebpackPlugin({
//此插件作用是将 index.html打包到bundle.js所在目录中
//同时会在 index.html中自动的在<script>引入 bundle.js
template : "./index.html"
})
]
}
3 在运行 webpack命令,在 dist/index.html会发现文件
关于作者
王硕,网名信平,十多年软件开发经验,业余架构师,精通Java/Python/Go等,喜欢研究技术,著有《PyQt 5 快速开发与实战》《Python 3.* 全栈开发》,多个业余开源项目托管在GitHub上,欢迎微博交流。