之前我们说过,webpack是默认不识别除js之外的其他类型的文件,那么引入css,less,scss文件,我们应该如何处理呢?
首先我们先写一段代码
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<!-- 解决没有favicon.ico时报错GET http://localhost:9999/favicon.ico 404 (Not Found) -->
<link rel="shortcut icon" href="#" />
<title>webpack学习</title>
</head>
<body>
<div>这是webpack学习</div>
<div id="root"></div>
<script src="./dist/main.js"></script>
</body>
</html>
index.js
import './src/assets/style/index.css';
const dom = document.getElementById('root');
const styleShowCssOne = document.createElement('div');
styleShowCssOne.innerText = 'StyleShowCSS 红色字体';
styleShowCssOne.className = 'red-font-css'
dom.append(styleShowCssOne);
index.css
.red-font-css {
color: red;
}
webpack.config.js
const path = require('path'); // 由于webpack无法直接操作文件夹,所以需要引入node的path模块
module.exports = {
entry: {
main: './index.js', // 指定当前目录的index.js为打包的入口文件
// 实际上是 entry: './index.js' 的具体写法,main为打包的Chunk Name
},
mode: 'development', // mode 指定打包模式(development(不会被压缩),production(这个模式的话代码会被压缩))
// development默认配置了sourcemap
// development默认无tree shaking配置,需要额外配置
output: {
filename: '[name].js', // 打包后输出的打包文件的文件名,根据entry的chunk name作为输出文件名(如果entry有多个入口文件时必须用占位符这样设置output.filename)
path: path.resolve(__dirname, 'dist'), // 指定打包后输出的打包文件在当前webpack.config.js所在文件夹的绝对路径的dist文件夹下
// path值必须是绝对路径 ,所以引入path包,__dirname代表当前webpack.config.js所在文件夹的绝对路径
// 整体路径为第一个参数+第二个参数,即__dirname + dist
// 是所有输出文件的目标路径(物理路径, 存储路径);
publicPath: '/' // (url 相对于 HTML 页面所在文件夹的绝对路径 + 值)给output配置全局的publicPath,
// 这样各个loader打包出来的文件发布路径(引用地址)就是此全局publicPath + loader的options.outputPath
// (文件引用路径就是看这个)
// 是对页面引入资源的补充,比如img标签引入或者css引入等.
// 千万不能设错,应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
}
}
package.json
{
"name": "01_why_use",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"bundle": "webpack"
},
"keywords": [],
"author": "Boale_H",
"license": "ISC",
"devDependencies": {
"webpack": "^4.43.0",
"webpack-cli": "^3.3.11"
}
}
执行npm run bundle打包
打包报错,提示我们需要loader处理css文件
在webpack成长指北第6章—webpack的图片引入有讲过,当我们遇到非js文件,在打包的时候,我们就需要考虑使用loader来对这些文件进行处理,css文件也是如此
打包css需要两个loader,分别是css-loader和style-loader
npm i css-loader style-loader -D
修改一下webpack配置
const path = require('path'); // 由于webpack无法直接操作文件夹,所以需要引入node的path模块
module.exports = {
entry: {
main: './index.js', // 指定当前目录的index.js为打包的入口文件
// 实际上是 entry: './index.js' 的具体写法,main为打包的Chunk Name
},
mode: 'development', // mode 指定打包模式(development(不会被压缩),production(这个模式的话代码会被压缩))
// development默认配置了sourcemap
// development默认无tree shaking配置,需要额外配置
module: {
rules: [
// 将css打包到js中
{
test:/\.css$/,
use:[
'style-loader', //将 JS 字符串生成为 style 标签节点
'css-loader' //将 CSS 转化成 CommonJS 模块
]
},
]
},
output: {
filename: '[name].js', // 打包后输出的打包文件的文件名,根据entry的chunk name作为输出文件名(如果entry有多个入口文件时必须用占位符这样设置output.filename)
path: path.resolve(__dirname, 'dist'), // 指定打包后输出的打包文件在当前webpack.config.js所在文件夹的绝对路径的dist文件夹下
// path值必须是绝对路径 ,所以引入path包,__dirname代表当前webpack.config.js所在文件夹的绝对路径
// 整体路径为第一个参数+第二个参数,即__dirname + dist
// 是所有输出文件的目标路径(物理路径, 存储路径);
publicPath: '/' // (url 相对于 HTML 页面所在文件夹的绝对路径 + 值)给output配置全局的publicPath,
// 这样各个loader打包出来的文件发布路径(引用地址)就是此全局publicPath + loader的options.outputPath
// (文件引用路径就是看这个)
// 是对页面引入资源的补充,比如img标签引入或者css引入等.
// 千万不能设错,应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
}
}
接着我们尝试一下css嵌套,即index.css中引入B.css,看看是否会生效
index.css
@import './B.css';
.red-font-css {
color: red;
}
B.css
.blue-font-css {
color: blue;
}
index.js
import './src/assets/style/index.css';
const dom = document.getElementById('root');
const styleShowCssOne = document.createElement('div');
styleShowCssOne.innerText = 'StyleShowCSS 红色字体';
styleShowCssOne.className = 'red-font-css'
dom.append(styleShowCssOne);
const styleShowCssTwo = document.createElement('div');
styleShowCssTwo.innerText = 'StyleShowCSS 蓝色字体';
styleShowCssTwo.className = 'blue-font-css'
dom.append(styleShowCssTwo);
我们再次尝试css引入图片作为背景,看看能否打包成功
index.css
@import './B.css';
.red-font-css {
color: red;
}
.box {
width: 100px;
height: 100px;
background: url('../images/wjfIcon.png');
}
index.js
import './src/assets/style/index.css';
const dom = document.getElementById('root');
const styleShowCssOne = document.createElement('div');
styleShowCssOne.innerText = 'StyleShowCSS 红色字体';
styleShowCssOne.className = 'red-font-css'
dom.append(styleShowCssOne);
const styleShowCssTwo = document.createElement('div');
styleShowCssTwo.innerText = 'StyleShowCSS 蓝色字体';
styleShowCssTwo.className = 'blue-font-css'
dom.append(styleShowCssTwo);
const styleShowCssThree = document.createElement('div');
styleShowCssThree.innerText = 'StyleShowCSS 背景图片';
styleShowCssThree.className = 'box'
dom.append(styleShowCssThree);
重新打包,打包失败,提示图片需要loader进行处理
我们安装file-loader和url-loader
npm i file-loader url-loader -D
修改webpack.config.js
const path = require('path'); // 由于webpack无法直接操作文件夹,所以需要引入node的path模块
module.exports = {
entry: {
main: './index.js', // 指定当前目录的index.js为打包的入口文件
// 实际上是 entry: './index.js' 的具体写法,main为打包的Chunk Name
},
mode: 'development', // mode 指定打包模式(development(不会被压缩),production(这个模式的话代码会被压缩))
// development默认配置了sourcemap
// development默认无tree shaking配置,需要额外配置
module: {
rules: [
// 将css打包到js中
{
test:/\.css$/,
use:[
'style-loader', //将 JS 字符串生成为 style 标签节点
'css-loader' //将 CSS 转化成 CommonJS 模块
]
},
{
test: /\.(jpg|png|gif)$/, // 对文件类型后缀进行匹配
use: {
loader: 'url-loader', // 使用url-loader对图片进行打包,如果url-loader的options没有设置limit,默认将所有静态文件全部打包成base64的字符串放到js里
options: {
esModule: false, // 新版本中esModule默认为true,会导致图片的地址变为[object Module],因此这里设置为false
name: '[name]_[hash].[ext]', // 输出的文件名为[原名称]_[哈希值].[原后缀]
outputPath: 'images/', // 文件存储路径(output.path + 值)(物理路径, 存储路径)
// 负责输出目录, 即打包后的写在磁盘的位置
limit: 2048 // 限制当文件小于2KB的时候,就将文件转为base64存储于js中,以减少http请求次数,当文件大于2KB,则打包文件到指定目录,避免js过大
}
}
},
]
},
output: {
filename: '[name].js', // 打包后输出的打包文件的文件名,根据entry的chunk name作为输出文件名(如果entry有多个入口文件时必须用占位符这样设置output.filename)
path: path.resolve(__dirname, 'dist'), // 指定打包后输出的打包文件在当前webpack.config.js所在文件夹的绝对路径的dist文件夹下
// path值必须是绝对路径 ,所以引入path包,__dirname代表当前webpack.config.js所在文件夹的绝对路径
// 整体路径为第一个参数+第二个参数,即__dirname + dist
// 是所有输出文件的目标路径(物理路径, 存储路径);
publicPath: 'dist/' // (url 相对于 HTML 页面所在文件夹的绝对路径 + 值)给output配置全局的publicPath,
// 这样各个loader打包出来的文件发布路径(引用地址)就是此全局publicPath + loader的options.outputPath
// (文件引用路径就是看这个)
// 是对页面引入资源的补充,比如img标签引入或者css引入等.
// 千万不能设错,应该观察文件和HTML页面的存储地址位置,进行设置,否则引用时地址会错误,找不到文件
}
}
css-loader有以下配置项
我们可以根据需要更改css-loader的配置项
如
{
test:/\.css$/,
use:[
'style-loader', //将 JS 字符串生成为 style 标签节点
// 'css-loader' //将 CSS 转化成 CommonJS 模块
{
loader: 'css-loader', //将 CSS 转化成 CommonJS 模块
options: {
import: true, // 启用/禁用 @import 处理
modules: true // 代表样式的模块化打包,即哪个js引入了样式,哪个js才会受这个样式作用,其他js不受此样式文件影响
// 但是这样会造成样式文件打包后,类名会变成hash值,造成样式不起作用,因此如果设置modules: true,组件中设置类名的方式则需要做调整,根据css文件类名的变化而变化
}
},
]
},
之前的配置,我们并没有看见dist目录出现css文件,这是因为css被打包到了main.js里
有时候需要将css提取出来存放到服务器中,如果想css打包成单独的文件,应该如何处理呢?
我们可以使用mini-css-extract-plugin插件,独立打包出css文件,并在html中引用对应的css文件
npm install mini-css-extract-plugin -D
修改webpack.config.js
备注:需要特别注意的是,mini-css-extract-plugin是将css打包成独立的文件,而style-loader是将css以