webpack loader篇|博客系列
# loader篇
webpack 可以使用 loader 来预处理文件。这允许你打包除 JavaScript 之外的任何静态资源。你可以使用 Node.js 来很简单地编写自己的 loader。
loader的配置有三种方式:
- 通过在webpack配置中的module.rules配置(最推荐的方式)
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /.txt$/,
use: 'raw-loader' // 获取到内容
}
]
}
}
- 内联的方式(使用
!将资源中的loader分开)
// 单个loader
import Styles from 'style-loader!./styles.css';
// 多个loader且带参数
import Styles from 'style-loader!css-loader?modules!./styles.css';
- 命令行CLI
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
会对 .jade 文件使用 jade-loader,对 .css 文件使用 style-loader 和 css-loader。
以下所有教材案例GitHub地址: LinDaiDai/webpack-loader
# 文件
# raw-loader
加载文件原始内容.
例如加载text文件:
import txt from './assets/file.txt'
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /.txt$/,
use: 'raw-loader' // 获取到内容
}
]
}
}
# file-loader
将文件发送到输出文件夹,并返回(相对)URL
也就是使用了file-loader的资源文件在打包后会输出到dist文件夹中, 同时如果用import或者require引入的话获取到的是相对路径.
# 1. js代码加载图片
例如加载img文件:
import img from './assets/file.png'
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [
'file-loader' // 得到的是bundle中的相对路径 4sj89003nknkdsdf.png
}
]
}
]
}
}
这里又一点需要注意的⚠️:
如果你是使用import引用的话得到的是图片的相对路径
如果是使用require引用的话得到的是一个模块对象, 这时候需要需要配置loader的一个参数options.esModule为false 才会得到相对路径.
// require引入
const img = require('./assets/file.png')
// 得到模块对象
Module{ defalut: '4sj89003nknkdsdf.png' }
// webpack.config.js 中配置参数
rules: [{
loader: 'file-loader',
options: {
esModule: false
}
}]
配置了esModule之后, 就能和import引入得到的一样了.
# 2. html加载图片
在html中加载一张图片:
<img src="./assets/file.png" />
这里默认应该是以CommonJS的加载方式加载的, 所以需要配置options.esModule为false, 如上面👆.
# 1. 基本用法
rules: [{
test: /\.(png|svg|jpg|gif)$/,
use: [{
loader: 'url-loader'
}]
}]
import img from './assets/file.png' // base64格式
const img from './assets/file.png' // Module: { default: data:image/png;base64... }
<img src="./assets/file.png" > // <img src="[object Module]" />
# 2. 参数limit
默认情况下它有一个参数limit是为undefined的, 此时获取文件返回的是base64格式(也就是dataURL).
但如果设置了limit(单位为K)同时文件的大小超过了这个limit的话, 就和file-loader一样返回bundle中的相对路径.
- 不设置
limit, 返回base64格式 - 设置了
limit, 小于该值, 返回base64格式 - 设置了
limit, 大于该值, 交给file-loader处理, 如果没有安装配置file-loader的话就会报错
例如加载下面👇两个img文件:
import img from './assets/file.png' // < 40KB data:image/png;base64
import wpl from './assets/wpl.png' // > 40KB 0565680d883d2c278e70d23f5ee97975.png
var imgEle = new Image()
var wplEle = new Image()
imgEle.src = img
wplEle.src = wpl
document.body.appendChild(imgEle)
document.body.appendChild(wplEle)
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.(png|svg|jpg|gif)$/,
use: [
// 'file-loader' // 得到的是bundle中的相对路径 4sj89003nknkdsdf.png
{
loader: 'url-loader', // 得到的是base64格式: data:image/png;base64
options: {
limit: 40000 // 超过40KB则返回 4sj89003nknkdsdf.png
}
}
]
}
]
}
}
旦如果你是想直接在标签中使用一张图片的话, 例如这样:
<img src="./assets/LinDaiDai.png" />
它并不能像预期那样, 它得到的是一个对象:
这个对象长成这样:
Module{
default: "data:image/png;base64,..."
}
所以对应页面上是不能正常显示的:
<img src="[object Module]" />
此时可以配置options中的esModule选项为false, 默认这个选项是为true的.
{
loader: 'url-loader',
options: {
esModule: false
}
}
在其他的loader, 例如raw-loader也有这样选项.
# svg-inline-loader
使用url-loader来处理svg文件, 是能将该文件转化为base64格式.
而svg-inline-loader的作用是将SVG内联为模块.
它会将引入的SVG转化为字符串.
安装:
$ cnpm i --save-dev svg-inline-loader
配置:
{
test: /\.svg$/,
loader: 'svg-inline-loader?classPrefix'
}
使用:
// src/print.js
const svg = require('./assets/add-icon.svg')
// import svg from './assets/add-icon.svg'
console.log(svg)
得到的是:
<svg version="1.1" id="图层_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 16 16" style="enable-background:new 0 0 16 16;" xml:space="preserve"><style type="text/css"> .fnCkiuXst0{fill-rule:evenodd;clip-rule:evenodd;fill:#888888;} </style><g><g><polygon class="fnCkiuXst0 " points="13,7 9,7 9,3 7,3 7,7 3,7 3,9 7,9 7,13 9,13 9,9 13,9 "></polygon></g></g></svg>
# 转换编译
# ts-loader
像 JavaScript 一样加载 TypeScript 2.0+
也就是能让你的代码中能写ts类型的文件.
ts-loader必须配合typescript一起使用.
所以在安装时:
$ cnpm i --save-dev ts-loader typescript
同时要在根目录下创建一个tsconfig.json文件:
{
"compilerOptions": {
"sourceMap": true
}
}
完成上述步骤就可以在项目中使用ts了.
让我们写个案例看看:
test.ts:
export function numToWord(num: number): string {
return config[num]
}
const config = {
1: 'one',
2: 'two'
}
然后使用它:
print.js:
import { numToWord } from './assets/test.ts'
console.log(numToWord(2)) // two
# babel-loader
下面介绍一个比较重要的loader: babel-loader.
我们都知道Babel就是一个JS编译器, 主要用于在旧的浏览器或环境中将ECMAScript 2015+代码转换为向后兼容版本的JavaScript代码。
