03

it2026-08-08  3

目标:

能处理css,less文件,解决css的浏览器兼容性配置能处理字体文件能处理图片文件能处理js降级问题

在webpack看来 一切皆模块,图片,样式文件,js文件… 。 但是webpack默认只能处理js模块,对于非js的内容它就需要一些帮手来处理了。这些帮手就是loader。

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。

处理css文件

下面,我们来讨论如何处理.css文件。

创建.css文件

在src目录下,再次创建一个css目录

|-src |-src/css |--------public.css |--------style.css

src/css/public.css的内容如下

body,html{ padding:0; font-size:14px; }

src/css/style.css的内容如下

@import "public.css"; div { border:4px solid #ccc; width: 50%; height: 200px; margin:30px auto; box-shadow: 3px 3px 3px #ccc; background-color: #fff; text-align: center; }

说明:

@import语句用来导入另一个css文件。

如果希望在.html文件中使用style.css样式,我们以前只学习过一种方式:直接在.html中通过link的方式来引入 。

那如果在js中引入了css会怎么样呢?

在.js中导入css

下面,我们修改自已的main.js,在 src/js/main.js中,引入css。

// nodejs中的模块化 const { updateDom } = require('./tool') + import '../css/style.css' updateDom ('app','index.html') log('test')

再次,打包代码,会报错。

ERROR in ./src/css/style.css 1:0 Module parse failed: Unexpected character '@' (1:0) You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders > @import "public.css"; | div { | padding:20px; @ ./src/js/main.js 4:0-26

上面报错的原因是:webpack把.css文件内容当作了js代码来运行,那当然会报错了。所以,解决方法是安装相应的loader来处理。

安装并使用css-loader

对于所有的loader的使用,其基本步骤是一致的,分成两步:

安装loader包 配置webpack.config.js中的module

安装

npm i css-loader -D -------------------- + css-loader@4.1.1 added 16 packages from 51 contributors in 14.718s 7 packages are looking for funding

它也是开发依赖。

在配置文件中使用

修改webpack.config.js文件,添加modules

const path = require('path') module.exports = { mode: 'development', entry:'./src/js/main.js', output:{ path:path.resolve(__dirname, './build'), filename:'bundle.js' }, + module:{ // 处理非js模块 + rules:[ // 规则 + { + test: /\.css$/, // 正则测试 + use: ['css-loader'] // loader + } + ] + } }

再次打包

它不会报错。但是,页面上也并没有出现样式的效果。打包之后的文件中并没有包含css代码。

安装并使用style-loader

如果我们希望样式生效,最终在.html文件中有两种情况:

有style标签有link标签

而css-loader只是能让你在.js中通过import来引入.css,如果你希望引入的css代码最终以style标签的方式插入到html页面中,则还需要安装一个loader:style-loader

安装

npm i style-loader -D --------------- + style-loader@1.2.1 added 4 packages from 6 contributors in 13.086s 8 packages are looking for funding run `npm fund` for details

配置

// node 中的核心模块 const path = require('path') // __dirname: 全局变量,指向当前目录绝对地址 // console.log(__dirname) // // path.join是拼接 // console.log( path.join(__dirname, 'dist123') ) // 1. 导出一个配置 // 2. mode, entry, output...... 都是webpack这个工具约定的配置名称 // 每一项都有自己的作用 // 3. 学习webpack 就是学习webpac.config.js中的配置项的使用方式 module.exports = { // mode: 'production', mode: 'development', // devtool: 'source-map', // devtool: 'inline-source-map', // 入口 // 默认入口:src/index.js entry: './src/js/index.js', // 出口 // 默认出口: dist/main.js output: { filename: 'main.js', // path: 必须是一个绝对路径 path: path.join(__dirname, 'build') }, module: { rules: [ // 每一个对象就是一条规则. // test: 匹配 // use: 对匹配到的模块采用对应的loader { test: /\.css$/, // 正则匹配 .css文件 // 匹配成功后(从后向前;从右到左) // 1. 先用css-loader去加载.css文件 // 2. 再用style-loader把样式以style标签的方式嵌入到html中 use: ['style-loader', 'css-loader'] } ] } }

Tip: 在有多个loader的情况下,use数组中的loader执行顺序是从右到左的过程。即:

先用css-loader来处理css再用style-loader把css代码插入到html中的style标签中。

打包查看效果

index.html

<!DOCTYPE html> <html lang="zh"> <head> <meta charset="UTF-8"> <title>index</title> <!-- <link rel="stylesheet" href="./css/style.css"> --> </head> <body> <div id="app"> </div> <!-- 引入两个js文件 --> <!-- <script src="./index.js"></script> <script src="./tool.js"></script> --> <!-- 引入打包之后的js --> <script src="../build/main.js"></script> </body> </html>

现在就能看到css的效果了 。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-CyA3T8Jn-1603365751269)(asset/image-20200731143422794.png)]

原理是:

bundle.js中有一些js代码,它在运行时,会自动在.html文件中追加style标签,并输出样式。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uF2nJvhN-1603365751271)(asset/image-20200603143508746.png)]

拓展

你可以分析打包之后代码,来验证style-loader的工作原理。在main.js中,可以找到类似如下的代码:

eval("var api = __webpack_require__(/*! ../../node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js */ \"./node_modules/style-loader/dist/runtime/injectStylesIntoStyleTag.js

再去node_modules\style-loader\dist\runtime\injectStylesIntoStyleTag.js 找下insertStyleElement这个方法,你就可以发现这个过程。

loader使用小结

在webpack看来,一切皆模块: 每一个文件都是一个模块。

webpack默认只能处理json和js模块,对于其它的模块它需要对应的loader来处理

loader的基本使用是:

安装Loader (npm 包)配置module中的rules:用loader来处理对应类型的文件

处理less文件

目标:在项目中支持使用less来写css代码。

改进案例

创建less文件

在src目录的css目录下创建 index.less,则内容如下:

@import "style.css"; body{ div { padding:50px; } }

在.js中引用.less

在src/js/main.js文件中引入less

// nodejs中的模块化 const { updateDom } = require('./tool') // es6中的模块化 import {log} from './tooles6' - import '../css/style.css' + import '../css/index.less' updateDom ('app','index.html') log('test')

安装并配置loader包

less less-loader

参考官网

npm i less-loader less -D ------------------------- + less@3.11.2 + less-loader@6.1.0 added 50 packages from 123 contributors in 23.883s less 用来把less–>cssless-loader用来加载less文件。

配置模块

在rules中添加一个配置,专门针对less文件。

/** 1. 要放在项目的根目录下。 2. 在npx webpack打包时,会自动去找这个文件,并运行其中的 代码。如果找不到,则进入零配置模式 ---- 采用一些默认配置。 */ // nodejs中一个核心模板 console.log('打包文件....') const path = require('path') module.exports = { // mode: 'development', mode: 'production', devtool: 'cheap-module-source-map', entry: './src/js/main.js', // 入口 output: { // 拼接一个绝对路由 path: path.join(__dirname, './build'), filename: 'bundle.js' }, // 非js模块要如何处理? 在module中定义 module: { // 规则 rules: [ { test: /\.css$/, // 如果这个模块以css结尾 // 如果在打包的过程遇到了.css,则: // 1. 先用css-loader读出内容 // 2. style-loader把读出的内容以style标签的格式 // 附加在.html文件上 use: ['style-loader', 'css-loader'] // 设置要处理的loader }, { test: /\.less$/, // 如果这个模块以less结尾 // 如果在打包的过程遇到了.less,则:从右向左 // 1. 先用less-loader 读出内容,转成css // 2. 用css-loader 读出内容 // 3. style-loader把读出的内容以style标签的格式 // 附加在.html文件上 use: ['style-loader','css-loader', 'less-loader'] // 设置要处理的loader } ] } }

注意:如上配置中,对于less文件的处理涉及三个loader,其处理顺序是less-loader --> css-loader–>style-loader。

less-loader:用来加载less文件,并处理成csscss-loader:用来加载css文件style-loader:用来将css代码以style标签的格式插入到html文件中

自动添加css样式前缀

目标:通过postcss及相关工具来处理兼容性问题—自动添加样式前缀

步骤

安装依赖

补充loader

单独设置postcss

安装依赖

npm i postcss postcss-loader autoprefixer -D

补充loader

{ test: /\.less$/, // 匹配成功后(从后向前;从右到左) // 1. 先用less-loader去加载.less文件,转成css // 2. 用postcss-loader配合autoprofixer加浏览器前缀 // 3. 先用css-loader去加载css文件 // 4. 再用style-loader把样式以style标签的方式嵌入到html中 use:['style-loader', 'css-loader', 'postcss-loader', 'less-loader'] }

单独设置 postcss.config.js

const autoprefixer = require('autoprefixer') module.exports = { plugins:[ autoprefixer({ // last 2 versions : 浏览器最近的2版本 // >1% 全球市场占有率在1%以上的浏览器 // overrideBrowserslist: ['last 2 versions', '> 1%'] }) ] }

默认是兼容所有最新版本

例子说明> 1%全球超过1%人使用的浏览器> 5% in US指定国家使用率覆盖last 2 versions所有浏览器兼容到最后两个版本根据CanIUse.com追踪的版本Firefox ESR火狐最新版本Firefox > 20指定浏览器的版本范围not ie <=8方向排除部分版本Firefox 12.1指定浏览器的兼容到指定版本unreleased versions所有浏览器的beta测试版本unreleased Chrome versions指定浏览器的测试版本since 20132013年之后发布的所有版本

特别地:对于要支持的浏览器的设置,也可以写在package.json中

{ // ...... "browserslist": "ie 10" }

如果只支持ie 10 ,则flex只会加-ms-前缀

查看当前支持的浏览器的列表npx browserslist

file-loader-处理字体文件

目标:在项目中支持字体文件

步骤:

在src中添加字体文件及对应的css

-src ----/css --------iconfont.css ----/fonts --------iconfont.woff

在index.html中引用

<div id="app"></div> <span class="icon-book iconfont"></span>

安装loader

npm i file-loader -D

配置文件

{ test:/\.woff$/, use:{ loader: 'file-loader', options: { // [name]: 这里[]表示里面放一个占位符。name就是要处理的文件名 // [ext]: 这里[]表示里面放一个占位符。ext就是要处理的文件后缀名 name: '[name].[ext]', outputPath: './fonts' } } }

file-loader的作用就是拷贝

url-loader处理图片

参考链接:npm官网

目标:在项目中支持对图片的处理:如果足够小就直接生成对应的base64编码值,否则就直接拷贝到制定位置。

修改代码

提前准备图片

在src下新增目录:img,并在其下放置两张图片:一张图片大一些,一张图片小一些(可以自己找图片)。 webpack.png: 49.4kbwebpack.svg: 3kb

在css中引入图片

在style.css中引入图片,作为div标签的background。 @import "public.css"; div { border:4px solid #ccc; width: 50%; height: 200px; margin:30px auto; box-shadow: 3px 3px 3px #ccc; background-color:pink; text-align: center; + background-image: url('../img/webpack.png') } body { + background-image: url('../img/webpack.svg') }

直接打包,会报错。报错的原因是.svg, .png格式的文件webpack并不能直接处理。

把上面的配置文件中的file-loader直接改成url-loader,就会实现拷贝的功能。

增强版的file-loader —> url-loader

npm i url-loader -D { test: /\.(png|svg|jpg)$/, // jpg use: { loader: 'url-loader', // url-loader是增强版的file-loader // 如果图片小于指定的大小,则会转成base64,否则就调用file-loader进行拷贝 options: { limit: 3*1024, // 如果图片小于3k就转成base64,否则就直接拷贝 name: '[name].[ext]', outputPath: './img' } } }

使用babel-loader处理js降级问题

能够把es6高级内容变为es5的loader名称为 babel-loader

es6/es7/es8等等高级标准有很多(let、箭头函数、对象解构赋值、…展开运算符、字符串模板等等),每个标准都需要一个独立的plugin进行降级处理,如果使用许多高级标准内容,那么势必要为此安装许多plugin,这样工作比较繁琐,系统已经考虑到这点了,其通过preset把许多常用的plugin给做了集合,因此一般性的使用只需要安装preset即可搞定(如果项目应用到了一个生僻的高级标准内容,preset处理不来,就还需要再安装对应的plugin处理)

npm官网: babel-loader

babel官网:https://www.babeljs.cn/setup#installation

步骤:

安装依赖包

npm i babel-loader @babel/core @babel/preset-env -D

在webpack.config.js中做如下配置:

{ test: /\.js$/, exclude: /node_modules/, // 排除目录 use: [ { loader:'babel-loader', options: { presets: ['@babel/preset-env'] } } ] // es6转es5 }

说明: @babel/preset-env用来指定按什么样的预设来进行降级处理

打包测试

打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。

小结

一切皆模块,非js模块有对应的loader来处理loader使用的基本步骤 第一步:安装包 cn/setup#installation

步骤:

安装依赖包

npm i babel-loader @babel/core @babel/preset-env -D

在webpack.config.js中做如下配置:

{ test: /\.js$/, exclude: /node_modules/, // 排除目录 use: [ { loader:'babel-loader', options: { presets: ['@babel/preset-env'] } } ] // es6转es5 }

说明: @babel/preset-env用来指定按什么样的预设来进行降级处理

打包测试

打包之后,去打包后的文件中检查是否已经把const和箭头函数这种es6的代码转成了es5的代码。

小结

一切皆模块,非js模块有对应的loader来处理loader使用的基本步骤 第一步:安装包第二步:配置rules
最新回复(0)