Loader 就像是一个翻译员,能把源文件经过转化后输出新的结果,并且一个文件还可以链式的经过多个翻译员翻译。

loader参考文章:https://webpack.docschina.org/loaders/

以处理 SCSS 文件为例:

  1. SCSS 源代码会先交给 sass-loader 把 SCSS 转换成 CSS;
  2. 把 sass-loader 输出的 CSS 交给 css-loader 处理,找出 CSS 中依赖的资源、压缩 CSS 等;
  3. 把 css-loader 输出的 CSS 交给 style-loader 处理,转换成通过脚本加载的 JavaScript 代码;

可以看出以上的处理过程需要有顺序的链式执行,先 sass-loader 再 css-loader 再 style-loader。

Loader 的职责

一个 Loader 的职责是单一的,只需要完成一种转换。
如果一个源文件需要经历多步转换才能正常使用,就通过多个 Loader 去转换。
在调用多个 Loader 去转换一个文件时,每个 Loader 会链式的顺序执行,
第一个 Loader 将会拿到需处理的原内容,上一个 Loader 处理后的结果会传给下一个接着处理,最后的 Loader 将处理后的最终结果返回给 Webpack。

所以,在开发一个 Loader 时,需要保持其职责的单一性,我们只需关心输入和输出。

了解一些loader

Babel

babel 可以让我们使用 ES2015/16/17 写代码而不用顾忌浏览器的问题,Babel 可以帮我们转换代码。首先安装必要的几个 Babel 库

npm i --save-dev babel-loader babel-core babel-preset-env

先介绍下我们安装的三个库

  • babel-loader 用于让 webpack 知道如何运行 babel
  • babel-core 可以看做编译器,这个库知道如何解析代码
  • babel-preset-env 这个库可以根据环境的不同转换代码

安装完后需要更改 webpack-config.js 中的代码

module.exports = {
// ......
module: {
rules: [
{
// js 文件才使用 babel
test: /\.js$/,
// 使用哪个 loader
use: 'babel-loader',
// 不希望babel处理的文件所在的路径
exclude: /node_modules/
}
]
}
}

配置 Babel 有很多方式,这里推荐使用 .babelrc 文件管理(如果此文件没有,则新建一个)。

// ..babelrc
{
"presets": ["babel-preset-env"]
}

 babel-polifill插件

在上面的babel配置中,babel只是将一些es6,es7-8的语法转换成符合目标的js代码,但是如果我们使用一些特性或方法,比如Generator, Set, 或者一些方法。babel并不能转换为低版本浏览器识别的代码。这时就需要babel-polifill。

简单的说,polifill就是一个垫片,提供了一些低版本es标准对高级特性的实现。使用polifill的方法如下:

npm install --save babel-polifill

然后在应用入口引入polifill,要确保它在任何其他代码/依赖声明前被调用。

//CommonJS module
require('babel-polyfill'); //es module
import 'babel-polifill';

在webpack.config.js中,将babel-polifill加入entry数组中:

entry: ["babel-polifill", "./app.js"]

相比于runtime-transform,polifill用于应用开发中。会添加相应变量到全局,所以会污染全局变量。

更多细节参考babel-polifill

runtime-transform插件

runtime transform也是一个插件,它与polifill有些类似,但它不污染全局变量,所以经常用于框架开发。

npm install --save-dev bable-plugin-transform-runtime

npm install --save bable-runtime

用法:将下面内容添加到.bablerc文件中

{
"plugins": ["transform-runtime"]
}

更多细节参考bable-runtime-transform插件

处理图片

使用 url-loader 和 file-loader,这两个库不仅可以处理图片,还有其他的功能

npm i --save-dev url-loader file-loader

创建一个 images 文件夹,放入两张不同大小的图片,并且在 app 文件夹下创建一个 js 文件处理图片 ,目前的文件夹结构如图

// addImage.js
let smallImg = document.createElement('img')
// 必须 require 进来
smallImg.src = require('../images/small.jpeg')
document.body.appendChild(smallImg) let bigImg = document.createElement('img')
bigImg.src = require('../images/big.jpeg')
document.body.appendChild(bigImg)

修改 webpack.config.js 代码

module.exports = {
// ...
module: {
rules: [
// ...
{
// 图片格式正则
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
// 配置 url-loader 的可选项
options: {
// 限制 图片大小 10000B,小于限制会将图片转换为 base64格式
limit: 10000,
// 超出限制,创建的文件格式
// build/images/[图片名].[hash].[图片格式]
name: 'images/[name].[hash].[ext]'
}
}
]
}
]
}
}

运行 npm run start,打包成功

可以发现大的图片被单独提取了出来,小的图片打包进了 bundle.js 中。

在浏览器中打开 HTML 文件,发现小图确实显示出来了(小图片实际上转化为base64位格式了),但是却没有看到大图,打开开发者工具栏,可以发现我们大图的图片路径是有问题的,所以我们又要修改 webpack.config.js 代码了。

module.exports = {
entry: './app/index.js', // 入口文件
output: {
path: path.resolve(__dirname, 'build'), // 必须使用绝对地址,输出文件夹
filename: "bundle.js", // 打包后输出文件的文件名
publicPath: 'build/' // 知道如何寻找资源
}
// ...
}

重新编译下,就OK啦

处理 CSS 文件

添加 styles 文件夹,新增 addImage.css 文件,然后在该文件中新增代码

使用 css-loader 和 style-loader 库。前者可以让 CSS 文件也支持 import,并且会解析 CSS 文件,后者可以将解析出来的 CSS 通过标签的形式插入到 HTML 中,所以后面依赖前者。

npm i --save-dev css-loader style-loader

addImage.js 文件中引入css文件

import '../styles/addImage.css'

修改 webpack.config.js 代码

module.exports = {
// ...
module: {
rules: [
{
test: /\.css$/,
use: ['style-loader',
{
loader: 'css-loader',
options: {
modules: true
}
}
]
},
]
}
}

运行下 npm run start,然后刷新页面,可以发现图片被正确的加上了边框,看一下 HTML 的文件结构

可以看到,我们在 addImage.css 文件中写的代码被加入到了 style 标签中,并且因为我们开启了 CSS 模块化的选项,所以 .test 被转成了唯一的哈希值,这样就解决了 CSS 的变量名重复问题。

但是将 CSS 代码整合进 JS 文件也是有弊端的,大量的 CSS 代码会造成 JS 文件的大小变大,操作 DOM 也会造成性能上的问题,所以接下来我们将使用 extract-text-webpack-plugin 插件将 CSS 文件打包为一个单独文件

npm i --save-dev extract-text-webpack-plugin

注意:如果是webpack4+

npm install extract-text-webpack-plugin@next

否则报错

修改 webpack.config.js 代码

const ExtractTextPlugin = require("extract-text-webpack-plugin")

module.exports = {
// ....
module: {
rules: [
{
test: /\.css$/,
// 写法和之前基本一致
loader: ExtractTextPlugin.extract({
// 必须这样写,否则会报错
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
modules: true
}
}]
})
]
}
]
},
// 插件列表
plugins: [
// 输出的文件路径
new ExtractTextPlugin("css/[name].[hash].css")
]
}

运行下 npm run start,可以发现 CSS 文件被单独打包出来了

这时候我们看到build文件夹里面多出了一个新的css文件夹。但是我们发现css文件并没有自动引入到html中

于是,需要安装新的插件

npm install html-webpack-plugin --save-dev

修改 webpack.config.js 代码

// 自带的库
const path = require('path')
const ExtractTextPlugin = require("extract-text-webpack-plugin")
const HtmlWebpackPlugin = require("html-webpack-plugin") module.exports = {
entry: './app/index.js', // 入口文件
output: {
path: path.join(__dirname, 'dist'), // 必须使用绝对地址,输出文件夹(打包后的文件存放的地方)
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
filename: '[name].[chunkhash].js',// 打包后输出文件的文件名
publicPath: './' // 知道如何寻找资源
},
module: {
rules: [
{
// js 文件才使用 babel
test: /\.js$/,
// 使用哪个 loader
use: 'babel-loader',
// 不包括路径
exclude: /node_modules/
},
{
// 图片格式正则
test: /\.(png|jpe?g|gif|svg)(\?.*)?$/,
use: [
{
loader: 'url-loader',
// 配置 url-loader 的可选项
options: {
// 限制 图片大小 10000B,小于限制会将图片转换为 base64格式
limit: 10000,
// 超出限制,创建的文件格式
// build/images/[图片名].[hash].[图片格式]
name: 'images/[name].[hash].[ext]'
}
}
]
},
{
test: /\.css$/,
loader: ExtractTextPlugin.extract({
fallback: 'style-loader',
use: [{
loader: 'css-loader',
options: {
modules: true
}
}]
})
},
]
},
// 插件列表
plugins: [
// 输出的文件路径
new ExtractTextPlugin("css/[name].[hash].css"), // 我们这里将之前的 HTML 文件当做模板
// 注意在之前 HTML 文件中请务必删除之前引入的 JS 文件
new HtmlWebpackPlugin({
template: 'index.html'
})
]
}

执行 build 操作会发现同时生成了 HTML 文件,并且已经自动引入了css和 JS 文件

打包之后的目录的文件夹结构如图

源码地址:https://github.com/zuobaiquan/webpack/tree/master/my_webpck

参考链接地址:https://segmentfault.com/a/1190000012718374

webpack学习记录-认识loader(二)的更多相关文章

  1. webpack学习记录 二

    开发网站 用polyfill(全局污染)  开发框架 用Runtime(局部污染) 在.babelrc文件中

  2. webpack 学习4 使用loader 以及常用的一些loader

    webpack本身只支持处理JavaScript,其他的文件,如css img less是不识别的,所以才会有loader这个东西,它就是可以使webpack能够处理其他非js文件的拓展程序 首先我们 ...

  3. 前段学习 之 webpack 学习记录

    自动化安装 1.安装node (node -v查看node版本) 2.全局安装vue-cli  Npm install -g vue-cli  Vue- v:查看是否安装成功  Vue list:查看 ...

  4. webpack学习记录

    webpack 中文网站  https://webpack.docschina.org/ webpack1 有编译打包 模块热更新 代码分割 文件处理功能 webpack2 tree Shaking( ...

  5. Webpack 学习记录之概念

    1 什么是webpack webpack是一个模块打包器,可以递归的构建一个依赖关系图,其中包含每个程序需要的每个模块,然后将所有模块打包成一个或多个bundle.他和其他的工具最大的不同在于他支持c ...

  6. webpack学习_资源管理(loader)

    webpack 最出色的功能之一就是,除了 JavaScript,还可以通过 loader 引入任何其他类型的文件 引入资源步骤 Step1:安装你需要的loader  Step2:在 module配 ...

  7. 个人学习记录1:二维数组保存到cookie后再读取

    二维数组保存到cookie后再读取 var heartsArray = [[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0],[0,0,0,0,0,0,0,0,0,0,0],[0,0, ...

  8. JavaWeb学习记录(十二)——商城购物之数据库操作的接口定义

    一.基本接口,该项目中所有接口都继承它 package blank.dao; import java.util.List; public interface BaseDao<T,PK> { ...

  9. JavaWeb学习记录总结(二十九)--Servlet\Session\Cookie\Filter实现自动登录和记住密码

    一.Servlet package autologin.servlet.login; import java.io.IOException;import java.security.MessageDi ...

随机推荐

  1. python 生成图形验证码

    文章链接:https://mp.weixin.qq.com/s/LYUBRNallHcjnhJb1R3ZBg 日常在网站使用过程中经常遇到图形验证,今天准备自己做个图形验证码,这算是个简单的功能,也适 ...

  2. Android 解决通过自定义设置打开热点后手机搜索不到热点的问题。

    开发过程中出现了通过自定义设置打开热点后手机搜索不到热点的问题. 后来通过观看  /data/misc/wifi  目录下的  hostapd.conf  文件,发现是 interface=ap0 d ...

  3. Windows server2008R2 企业内部搭建虚拟专用网络服务

    VPN英文全称是“Virtual Private Network”,就是“虚拟专用网络”.可以远程帮助用户.分公司.商业伙伴及供应商同公司的内部网建立可信的安全连接,用于经济有效地连接到商业伙伴和用户 ...

  4. "'cl' 不是内部或外部命令,也不是可运行的程序"解决方案

    最近使用VS2012+Qt5.1+QtCreator2.8.1来搭建Qt的开发环境(之前有用MinGW编译的经历,经常碰到gdb调试器崩溃的问题),全部换成想用VC的编译器和调试环境,但是觉得QtCr ...

  5. SQLServer删除数据

    使用SSMS删除数据 1.连接数据库.选择数据表->右键点击,选择所有行(或者选择前200行). 2.在数据窗口中选择数据行(注意点击最左边列选择整个数据行)->在最左侧右键点击-> ...

  6. 码农人生——从未学过Android如何开发Android App 案例讲解-第002期案例

    标题有点晃眼,本次分享是002期博文的实践故事,不会有任何代码.也不会教别人android 如何开发,类似博文已经有大批大批,而且还会有陆陆续续的人写,我写的文章,主要是经验之谈,希望总结出的一些方法 ...

  7. django 视图模式

    一 视图 FBV --- function based view(基于函数视图) CBV --- class based view(基于类的视图函数) 二 请求方式 get post put/patc ...

  8. css设置文字上下居中,一行文字居中,两行或多行文字同样居中。

    转:https://www.cnblogs.com/handsomeBoys/p/6599062.html HTML: <div class="book-detail-store-it ...

  9. Loj #2324. 「清华集训 2017」小 Y 和二叉树

    Loj #2324. 「清华集训 2017」小 Y 和二叉树 小Y是一个心灵手巧的OIer,她有许多二叉树模型. 小Y的二叉树模型中,每个结点都具有一个编号,小Y把她最喜欢的一个二叉树模型挂在了墙上, ...

  10. 移动端1px的解决办法之styled

    做项目的时候总结了一个styled中解决移动端项目1px像素线的问题,封装了一个函数,大家可以直接使用,很方便. 1 import styled from 'styled-components' co ...