webpack3-loader

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

webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。

处理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

在js文件中引入css,就像vue项目中引入第三方ui样式一样,如element-ui的使用说明中提到的:

import Vue from 'vue';
import ElementUI from 'element-ui';
// 引入 css
import 'element-ui/lib/theme-chalk/index.css';
import App from './App.vue';

Vue.use(ElementUI);

new Vue({
  el: '#app',
  render: h => h(App)
});

很明显,上面的.js代码中引入了.css。

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

// nodejs中的模块化
const { updateDom } = require('./tool')
// es6中的模块化
import {log} from './tooles6'

+ 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的使用,其基本步骤是一致的,分成两步:

    1. 安装loader包
    1. 配置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
配置
// nodejs模块,对整个打包过程做设置
const path = require('path')
// __dirname : 当前文件夹的绝对路径
// path.join(): 路径拼接
const pathValue = path.join(__dirname, 'dist123')

// console.log(pathValue)
module.exports = {
  // 设置打包的方式
  mode: "development",
  // 设置入口文件
  entry: "./src/js/main.js",
  // 设置出口文件
  output: {
    path:  pathValue,
    filename: 'abc.js'
  },
  // 用写loader的配置。用来处理那些 非js模块
  module: {
    rules:[ //规则: 什么文件,用什么loader来处理
      {
        test: /\.css$/, // 用正则匹配
        use:['style-loader','css-loader'] // 如果匹配成功,就使用Loader
        // 如果它是一个数组,则表示当匹配成功之后从右向左依次去使用loader。
        // css-loader: 允许你通过Import的方法引入css
        // style-loader: 可以把css以style标签的格式插入到html中
      }
    ]
  }
}

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>
  </head>
  <body>
    <div id="app">
      
    </div>
    <!-- 引入两个js文件 -->
    <!-- <script src="./tool.js"></script> -->
    <!-- <script src="./index.js"></script> -->
    <script src="./dist123/abc.js"></script>
</body>
</html>

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0b8qP0Xh-1596243713654)(asset/image-20200731143422794.png)]在这里插入图片描述

原理是:

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-vtLZWkts-1596243713657)(asset/image-20200603143508746.png)]在这里插入图片描述

拓展

你可以分析打包之后代码,来验证style-loader的工作原理。在bundler.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这个方法,你就可以发现这个过程。

处理less文件

如果希望处理less文件,则还需要去安装额外的包。

创建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')

安装包

参考官网

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–>css
  • less-loader用来加载less文件。

配置模块

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

module.exports = {
    // 非js模块,在这里处理
    module: {
        rules:[ //规则: 什么文件,用什么loader来处理
      {
        test: /\.css$/, // 用正则匹配
        use:['style-loader','css-loader'] // 如果匹配成功,就使用Loader
        // 如果它是一个数组,则表示当匹配成功之后从右向左依次去使用loader。
        // css-loader: 允许你通过Import的方法引入css
        // style-loader: 可以把css以style标签的格式插入到html中
      },
+      {
        test: /\.less$/, // 用正则匹配
        use:['style-loader','css-loader','less-loader'] // 如果匹配成功,就使用Loader
        // 如果它是一个数组,则表示当匹配成功之后从右向左依次去使用loader。
        // (1) less-loader: 把less加载,转成css
        // (2) css-loader: 允许你通过Import的方法引入css
        // (3) style-loader: 可以把css以style标签的格式插入到html中
+      }
    ]
    }
}

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

  • less-loader:用来加载less文件,并处理成css
  • css-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

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

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

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

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

url-loader-处理图片文件

参考链接:npm官网

如果在css(或者less)中通过url()引用了图片,则还需要使用特殊的url-loader。

在css中引入图片

  • src下新增目录:img,并在其下放置两张图片:一张图片大一些,一张图片小一些(可以自行决定)。

    • webpack.png: 49.4kb
    • webpack.svg: 3kb
  • 在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')
}

现在,直接打包,会报错。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-a4eoRdWX-1596243713660)(asset/image-20200603145626515.png)]在这里插入图片描述

原因:webpack它自已只能处理.js。

安装url-loader

npm i url-loader -D
------
+ url-loader@4.1.0
added 4 packages from 6 contributors in 6.171s

配置

module:{ // 
    rules:[
        // ...
        {
                test:/\.(png|svg)$/,// 正则匹配,以.png结尾的文件, 以.svg结尾的文件
                use:['url-loader'] // 匹配成功,使用指定的loader
            }
    ]
}

注意:

  • 正则表达式中的写法/\.(png|svg)$/ 表示可以匹配.png和.svg文件。

再次打包

检查它的效果:把图片文件转成base64编码。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-kMOnROa5-1596243713662)(asset/image-20200603150213249.png)]在这里插入图片描述

好处:减少一次网络请求

坏处:增加了文件的大小

在实操的过程,会把一个较小的图片文件转base64,这样虽然会增加打包文件的大小,但可以减少一次网络请求,划算!

但是,如是一个文件特别大,就不适合去转base64:它会急剧增长打包文件的大小 。

下面来精细设置它能直接处理的文件阈值。

设置文件阈值

在modules中补充配置:

{
    test:/\.(png|svg)$/,
    use:[
        {
            loader:'url-loader',
+            options:{
+                limit: 3 * 1024 // 限制大小为3k
+            }
        }
    ]
}

由于webpack.png的大小超过了上面的阈值,所以url-loader并不会处理这个图片文件,会报一个类似于如下的错误:

ERROR in ./src/img/webpack.png
Module build failed (from ./node_modules/url-loader/dist/cjs.js):
Error: Cannot find module 'file-loader'

报错的原因如下:当引入的文件大小大于或者等于指定的limit时,会交给file-loader来处理,同时把所有的参数也传给file-loader(参见这里的说明),而由于file-loader是另一个加载器,当前我们并没有安装它,所以报错了。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-TKfcxiuW-1596243713665)(asset/image-20200603152729013.png)]在这里插入图片描述

安装并使用file-loader

安装

npm i file-loader -D
-----------------------
+ file-loader@6.0.0
added 4 packages from 6 contributors and removed 26 packages in 13.844s

11 packages are looking for funding
  run `npm fund` for details

配置

不需要额外配置。如果url-loader处理不了,它会自动介入,file-loader会自动工作:它的处理结果是:

  • 找到这个文件
  • 复制一份,以hash值命名
  • 放在output设置的出口文件夹下。

打包测试

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-I4tAZ2yY-1596243713668)(asset/image-20200603153053111.png)]在这里插入图片描述

页面上还是不会正确地显示出图片来,因为这个file-loader只是负责把较大的图片移到打包出口文件夹,而不会把这个文件的地址信息更新到.css,或者是.html文件,这个工作需要我们去使用一个plugin来解决。

练习:babel-loader

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

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

let----降级---->plugin

箭头函数----降级—>plugin

npm官网: babel-loader

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

步骤:

  1. 安装依赖包

    npm i babel-loader @babel/core @babel/preset-env -D
    
  2. 在webpack.config.js中做如下配置:

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

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

  3. 打包测试

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

小结

  • 一切皆模块,模块有loader
  • loader
    • 第一步:安装包
    • 第二步:配置rules
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值