之前的webpack打包,只涉及到js文件本身,如果涉及到了使用其他语法的文件的话。比如说,css文件、使用了ES6语法的jsx(react)等,webpack就无法打包了。
可以试着用原来方法尝试对涉及css文件的文件进行打包。
文件如下:
index.css
body{
background-color: #333333;
}
hello.js
export default function(){
document.write('hello');
}
index.js
import hello from './hello'
import '../css/index.css'
document.write('我是index. ');
hello();
webpack.config.js
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'main.js'
}
};
直接打包会报错:
原因是webpack本身无法解析css类型的文件。这个时候,就需要配置相应的解析规则,去帮助解析css文件。
这个时候就需要配置module属性。module配置如何处理模块。在module中的rules属性中配置模块的读取和解析规则,通常用来配置 Loader。其类型是一个数组,数组里每一项都描述了如何去处理部分文件。 配置一项 rules 时大致通过以下方式:
rules数组中的对象属性在这里用到以下几种:
属性名 | 含义 |
include | 参数是字符串,代表绝对路径,只会在该目录下进行文件的命中。 通常通过Node.js 的path模块去获取绝对路径:path: path.resolve(__dirname, 'dist_[hash]') |
test | 参数可以是数组,也是一个正则,用于匹配文件的类型。只有能被匹配到文件类型,才能被命中,使用对象中的loader规则。 数组的话,只要被其中的一个元素匹配到了,就会命中该文件。 |
exclude | 参数可以是数组,也可以说是字符串,代表绝对路径,排除项目目录下的文件。 通常通过Node.js 的path模块去获取绝对路径:path: path.resolve(__dirname, 'dist_[hash]') |
use | 参数是数组,数组元素可以是字符串,也可是对象,代表选择哪类Loader。 Loader 可以看作具有文件转换功能的翻译员,配置里的 module.rules 数组配置了一组规则, 告诉 Webpack 在遇到哪些文件时使用哪些 Loader 去加载和转换。处理顺序一般为从后到前。 |
将webpackconfig.js改成如下文件:
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
// 命中 CSS 文件
test: /\.css$/,
// 排除 node_modules 目录下的文件,防止被打抱
exclude: path.resolve(__dirname, 'node_modules'),
// 只命中css目录里的css文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'css'),
use: [
'css-loader'
]
}
]
}
};
继续打包错误
因为,webpack并没有自带相应loader,需要npm下载才行。输入以下命令(全局是无效的):
npm install css-loader --save-dev
在该目录下的下载css-loader生产环境代码。
安装成功。继续打包。
成功之后创建index.html,调用打包后的js。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>index</title>
</head>
<body>
<script type="text/javascript" src="./dist/bundle.js"></script>
</body>
</html>
结果:
但是,没有css相关样式。因为css-loader只实现了,解析样式文件,并没有加载样式。所以,需要新的loader。输入以下npm命令:
npm install style-loader --save-dev
将webpack.config.js改成如下代码:
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
// 命中 CSS 文件
test: /\.css$/,
// 排除 node_modules 目录下的文件,防止被打抱
exclude: path.resolve(__dirname, 'node_modules'),
// 只命中css目录里的css文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'css'),
use: [
'css-loader',
'style-loader'
]
}
]
}
};
再次打包:
报错是因为'css-loader'在'style-loader'之前,而loader的执行是从后到前的,而stye-loader的执行需要css-loader做前提,所以报错了。
将webpack.config.js改成如下代码:
const path = require('path')
module.exports = {
entry: './src/index.js',
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js'
},
module: {
rules: [
{
// 命中 CSS 文件
test: /\.css$/,
// 排除 node_modules 目录下的文件,防止被打抱
exclude: path.resolve(__dirname, 'node_modules'),
// 只命中css目录里的css文件,加快 Webpack 搜索速度
include: path.resolve(__dirname, 'css'),
use: [
'style-loader',
'css-loader'
]
}
]
}
};
再次打包:
结果:
终于成功了!
小结:Module中的Loader在webpack的打包流程中,起到的作用是在获取的入口文件以及相关的文件之后,帮助识别原本webpack不能识别的代码。