4webpack中的loader
4.1loader概述
在实际开发过程中,webpack默认只能打包处理以 .js 后缀名结尾的模块。其他非 .js 后缀名结尾的模块,webpack默认处理不了,需要调用loader 加载器才可以正常打包,否则会报错!
loader加载器的作用:
协助webpack打包处理特定的文件模块。
比如:
css-loader 可以打包处理 .css 相关的文件
less-loader 可以打包处理 .less相关的文件
babel-loader 可以打包处理webpack无法处理的高级JS语法
4.2loader的调用过程
4.3打包处理css文件
4.3.1安装处理css文件的loader
npm i style-loader css-loader -D
4.3.2配置
在 webpack.config.js 的 module -> rules 数组中,添加loader规则如下:
rules:[{ test:/\.css$/, use:['style-loader', 'css-loader'] }]
其中,test表示匹配的文件类型,use表示对应要调用的 loader
注意:
use数组中指定的loader顺序是固定的
多个loader的调用顺序是:从后往前调用
配置后的 webpack.config.js
//导入html-webpack-plugin插件 得到插件的构造函数 const HtmlPlugin = require('html-webpack-plugin') // new构造函数创建插件的实例对象 const htmlPlugin = new HtmlPlugin({ // 指定要复制哪个页面 template: './src/index.html', // 指定复制出来的文件名和存放路径 filename: './index.html' }) // 使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports = { // 代表webpack运行的模式,可选值有两个development和production mode: 'development', // 插件的数组 将来webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin], devServer: { // 首次打包成功后自动打开浏览器 open:true, // 在http协议中如果端口号为80可以省略 port:8080, // 指定主机运行的地址 host:'127.0.0.1' }, module: { rules:[{ test:/\.css$/, use:['style-loader', 'css-loader'] }] } }
4.3.3配置完成后就可以导入css样式
在index.js文件中:
// 导入样式,在webpack中,一切皆模块,都可以通过es6导入语法进行导入和使用 import './css/index.css'
4.3.4过程解释
4.4打包处理less文件
4.4.1安装处理less文件的loader
npm i less-loader less -
4.4.2配置
在webpack.confing.js文件中的module->rules数组中添加:
module: { rules:[ {test:/\.css$/, use:['style-loader', 'css-loader']}, {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']} ] }
4.5打包处理样式表中与url路径相关的文件
4.5.1安装
npm i url-loader file-loader -D
4.5.2配置
在webpack.config.js 的 module -> rules数组中,添加loader规则如下︰
module: { //所有第三方文件模块的匹配规则 rules: [ //文件后缀名的匹配规则 { test: /\.jpg|png|gif$/,use: 'url-loader?limit=22229'}, ] }
其中 ? 之后的是loader的参数项:
limit用来指定图片的大小,单位是字节( byte)
只有≤limit 大小的图片,才会被转为base64格式的图片
补充:小图片适合转成base64,大图片不合适,转成base64图片体积会变大
4.5.3使用js给img标签导入图片
<!-- 需求:把 /src/images/01.jpg 设置给src属性 --> <img src="" alt="" class="box">
// 导入图片,得到图片文件 import i from './images/01.jpg' // 给img标签的src动态赋值 $('.box').attr( 'src', i )
4.5.4loader的另一种配置方式(带参数的loader)
module: { //所有第三方文件模块的匹配规则 rules: [ //文件后缀名的匹配规则 { test: /\.jpg|png|gif$/, use: { //通过loader属性指定调用的loader loader: 'url-loader', //通过option属性指定参数 options: { limit: 22229 } } } ] }
4.6打包处理js文件中的高级语法
webpack.只能打包处理一部分高级的JavaScript语法。对于那些webpack 无法处理的高级js语法,需要借助于babel-loader进行打包处理。
例如:
class Person { //webpack无法处理静态属性这个高级语法 static info = 'person info' } console.log( Person.info )
4.6.1安装
npm i babel-loader @babel/core @babel/plugin-proposal-class-properties -D
4.6.2配置
// 使用babel-loader处理高级的js语法 { test:/\.js$/, // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包 exclude: /node_modules/, use: { loader: 'babel-loader', options: { // 声明babel可用插件 // 此插件用来转化class中的高级语法 plugins: ['@babel/plugin-proposal-class-properties'] } } }
5打包发布
5.1为什么要打包发布
项目开发完成之后,使用webpack对项目进行打包发布的主要原因有以下两点:
开发环境下,打包生成的文件存放于内存中,无法获取到最终打包生成的文件
开发环境下,打包生成的文件不会进行代码压缩和性能优化
5.2配置webpack的打包发布
在package.json文件的scripts节点下,新增build命令如下:
"scripts" : { "dev" : "webpack serve", //开发环境中,运行 "build": "webpack --mode production" //项目发布时,运行 build命令 }
–model是一个参数项,用来指定webpack的运行模式。production代表生产环境,会对打包生成的文件进行代码压缩和性能优化。
注意:通过–model指定的参数项,会覆盖webpack.config.js 中的model选项。
5.3把JavaScript文件统一生成到js目录中
在 webpack.config.js 配置文件的 output节点中,进行如下的配置:
module.exports中
output: { path: path.join( __dirname, 'dist'), //明确告诉webpack把生成的 main.js 文件存放到 dist目录下的 js 子目录中 filename: 'js/main.js', }
5.4把图片文件统一生成到image目录中
module: { //所有第三方文件模块的匹配规则 rules: [ //文件后缀名的匹配规则 { test: /\.jpg|png|gif$/, use: { //通过loader属性指定调用的loader loader: 'url-loader', //通过option属性指定参数 options: { limit: 22229, outputPath: 'image' } } } ]
或
{ test:/\.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images' }
5.5自动清理dist目录下的旧文件
为了在每次打包发布时自动清理掉dist目录中的旧文件,可以安装并配置 clean-webpack-plugin 插件
5.5.1安装清理dist目录的 webpack插件
npm install clean-webpack-plugin -D
5.5.2配置
在 webpack.config.js 配置文件
module.exports中
const { CleanWebpackPlugin } = require( 'clean-webpack-plugin') const cleanPlugin = new CleanWebpackPlugin() //把创建的 cleanPlugin 插件实例对象,挂载到plugins节点中 plugins: [htmlPlugin,cleanPlugin], //挂载插件
6 Source Map
6.1 什么是Source Map
Source Map就是一个信息文件,里面储存着位置信息。也就是说,Source Map 文件中存储着压缩混淆后的代码所对应的转换前的位置。
有了它,出错的时候,除错工具将直接显示原始代码,而不是转换后的代码,能够极大的方便后期的调试。
Source Map 可以在报错时提示对应的源文件的行号,便于定位错误位置修改错误。
6.2 默认Source Map的问题
开发环境下默认生成的Source Map记录的是生成后的代码的位置。会导致运行时报错的行数与源代码的行数不一致的问题。示意图如下:
6.3 解决默认Source Map的问题
开发环境下,推荐在webpack.config.js中添加如下的配置,即可保证运行时报错的行数与源代码的行数保持一致:
module.exports = { mode: 'development', // eval-source-map 仅限在"开发模式"下使用,不建议在“生产模式"下使用。 //此选项生成的Source Map 能够保证"运行时报错的行数"与"源代码的行数"保持一致 devtool: 'eval-source-map' , //省略其他配置项... }
6.4 webpack生产环境下的Source Map
在生产环境下,如果省略了devtool选项,则最终生成的文件中不包含Source Map。这能够防止原始代码通过Source Map 的形式暴露给别有所图之人。
6.4.1只定位行数不暴露源码
在生产环境下,如果只想定位报错的具体行数,且不想暴露源码。此时可以将devtool的值设置为
nosources-source-map。实际效果如图所示:
在实际发布的时候,建议大家把 devtool 的值设置为nosources-source-map或直接关闭SourceMap。
6.4.2 定位行数且暴露源码
在生产环境下,如果想在定位报错行数的同时,展示具体报错的源码。此时可以将devtool的值设置为source-map。实际效果如图所示:
6.5 Source Map的最佳实践
开发环境下:
建议把devtool的值设置为eval-source-map
好处:可以精准定位到具体的错误行
生产环境下:
建议关闭Source Map 或将devtool的值设置为nosources-source-map
好处:防止源码泄露,提高网站的安全性
7 配置完成后的package.json与webpack.config.js
"scripts": { "dev": "webpack serve", "build": "webpack --mode production" },
// 使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports = { // devtool: 'eval-source-map', devtool: 'nosources-source-map', // 代表webpack运行的模式,可选值有两个development和production mode: 'development', entry: path.join(__dirname, './src/index.js'), output: { path: path.join(__dirname, 'dist'), filename: 'js/main.js' }, // 插件的数组 将来webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin,new CleanWebpackPlugin()], devServer: { // 首次打包成功后自动打开浏览器 open:true, // 在http协议中如果端口号为80可以省略 port:80, // 指定主机运行的地址 host:'127.0.0.1' }, module: { rules:[ {test:/\.css$/, use:['style-loader', 'css-loader']}, {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']}, // 处理图片文件的loader // 如果需要调用的loader只有一个,则只传递一个字符串就行,如果有多个loader则必须指定数组 { test:/\.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images' }, // 使用babel-loader处理高级的js语法 // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包 {test:/\.js$/, use: 'babel-loader', exclude: /node_modules/} ] } }
8 使用@代替./ …/
@代表src源代码目录
使用@从src开始向内查找
使用./ …/ 从当前文件向外查找
8.1 配置
webpack.config.js文件
const path = require('path') //导入html-webpack-plugin插件 得到插件的构造函数 const HtmlPlugin = require('html-webpack-plugin') // new构造函数创建插件的实例对象 const htmlPlugin = new HtmlPlugin({ // 指定要复制哪个页面 template: './src/index.html', // 指定复制出来的文件名和存放路径 filename: './index.html' }) const { CleanWebpackPlugin } = require('clean-webpack-plugin'); // 使用Node.js中的导出语法,向外导出一个webpack的配置对象 module.exports = { // devtool: 'eval-source-map', devtool: 'nosources-source-map', // 代表webpack运行的模式,可选值有两个development和production mode: 'development', entry: path.join(__dirname, './src/index.js'), output: { path: path.join(__dirname, 'dist'), filename: 'js/main.js' }, // 插件的数组 将来webpack在运行时会加载并调用这些插件 plugins: [htmlPlugin,new CleanWebpackPlugin()], devServer: { // 首次打包成功后自动打开浏览器 open:true, // 在http协议中如果端口号为80可以省略 port:8080, // 指定主机运行的地址 host:'127.0.0.1' }, module: { rules:[ {test:/\.css$/, use:['style-loader', 'css-loader']}, {test:/\.less$/, use:['style-loader', 'css-loader', 'less-loader']}, // 处理图片文件的loader // 如果需要调用的loader只有一个,则只传递一个字符串就行,如果有多个loader则必须指定数组 { test:/\.jpg|png|gif$/, use: 'url-loader?limit=22229&outputPath=images' }, // 使用babel-loader处理高级的js语法 // 注意:必须使用exclude排除指定项;因为node_modules目录下的第三方包不需要被打包 {test:/\.js$/, use: 'babel-loader', exclude: /node_modules/} ] }, resolve: { alias: { //告诉webpack @代表src这一层目录 '@' : path.join(__dirname, './src/') } } }