模块转换器 — Loader
loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!
loader 是对应用程序中资源文件进行转换。它们是(运行在 Node.js 中的)函数,可以将资源文件作为参数的来源,然后返回新的资源文件。
1、loader特性
loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
- loader 可以是同步的,也可以是异步的。
- loader 运行在 Node.js 中,并且能够执行任何可能的操作。
- loader 接收查询参数。用于对 loader 传递配置。
- loader 也能够使用 options 对象进行配置。
除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。
插件(plugin)可以为 loader 带来更多特性。
loader 能够产生额外的任意文件。
loader 通过(loader)预处理函数,为 JavaScript 生态系统提供了更多能力。 用户现在可以更加灵活地引入细粒度逻辑,例如压缩、打包、语言翻译和其他更多。
loader 遵循标准的模块解析。多数情况下,loader 将从模块路径(通常将模块路径认为是 npm install, node_modules)解析。
loader 模块需要导出为一个函数,并且使用 Node.js 兼容的 JavaScript 编写。通常使用 npm 进行管理,但是也可以将自定义 loader 作为应用程序中的文件。按照约定,loader 通常被命名为 xxx-loader(例如 json-loader)。
2、使用loader的三种方式
2.1、配置(推荐):在 webpack.config.js 文件中指定 loader
module.rules 允许你在 webpack 配置中指定多个 loader。 这是展示 loader 的一种简明方式,并且有助于使代码变得简洁。同时让你对各个 loader 有个全局概览:
module: { rules: [ { test: /\.css$/, use: [ { loader: 'style-loader' }, { loader: 'css-loader', options: { modules: true } } ] } ] }
Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置,Loaders的配置包括以下几方面:
(1)、test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
(2)、loader:loader的名称(必须)
(3)、include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(文件夹)(可选)
(4)、query:为loaders提供额外的设置选项(可选)
2.2、内联:在每个 import 语句中显式指定 loader
可以在 import 语句或任何等效于 "import" 的方式中指定 loader。使用 ! 将资源中的 loader 分开。分开的每个部分都相对于当前目录解析。
import Styles from 'style-loader!css-loader?modules!./styles.css';
通过前置所有规则及使用 !,可以对应覆盖到配置中的任意 loader。
选项可以传递查询参数,例如 ?key=value&foo=bar,或者一个 JSON 对象,例如 ?{"key":"value","foo":"bar"}。
尽可能使用 module.rules,因为这样可以减少源码中的代码量,并且可以在出错时,更快地调试和定位 loader 中的问题。
2.3、CLI:在 shell 命令中指定它们
你也可以通过 CLI 使用 loader:
webpack --module-bind jade-loader --module-bind 'css=style-loader!css-loader'
这会对 .jade 文件使用 jade-loader,对 .css 文件使用 style-loader 和 css-loader。
2.4、尝试使用loader加载器
2.4.1、使用webstrom创建一个空项目
2.4.2、初始化项目
npm init -y
初始化完效果如下:
2.4.3、安装webpack
webpack4需要安装webpack-cli:
npm i webpack webpack-cli --save-dev
安装完成:
2.4.4、安装lodash
npm i lodash --save
安装完成:
2.4.5、创建文件夹
效果如下:
2.4.6、raw-loader(文件原始内容转换器)
一个可以用于加载文件作为字符串使用的加载器,使用UTF-8编码。
安装:
npm i --D raw-loader
安装成功:
src/file.txt文件、内容自拟
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = flies; return element; } //在body中添加子元素 document.body.appendChild(component()); }
src.index.js
//入口文件 import bar from './bar'; bar();
webpack.config.js
//webpack配置文件 var path=require('path'); //定义一个默认模块对象 module.exports={ entry:{ idnex:"./src/index.js" }, output: { filename: "[name].task.js", path:path.resolve(__dirname,'dist') }, module: { rules: [{ test:/\.txt$/, use:'raw-loader' }] },
mode: "development"
}
index,html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> <script src="dist/idnex.task.js"></script> </body> </html>
完成后效果如下:
测试结果图下:
如上图所示,已经把我们开始创建得file.txt文件的额内容输出。
2.4.7、CSS Loader(样式处理)
安装:
npm i style-loader css-loader -D
定义样式与引用:
src/loaderTask.css
h1{ height: 40px; line-height: 40px; background: lightskyblue; color:#fff; }
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导入css文件 import css from './loaderTask.css'; //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = flies; return element; } //在body中添加子元素 document.body.appendChild(component()); }
配置:webpack.config.js
//webpack配置文件 var path=require('path'); //定义一个默认模块对象 module.exports={ entry:{ idnex:"./src/index.js" }, output: { filename: "[name].task.js", path:path.resolve(__dirname,'dist') }, module: { rules: [{ test:/\.txt$/, use:'raw-loader' },{ test: /\.css/, use: ['style-loader', { loader: 'css-loader', options: { modules:true, sourceMap: true } }] }] }, mode: "development" };
完成后效果图:
2.4.8、sass-loader(加载和转译 SASS/SCSS 文件)
安装:
npm i sass-loader node-sass --D
src/loaderTask.scss
$height:100px; $color:blue; h1{ width: 100%; height: $height; line-height: $height; background: $color; padding-left: $height/5; border-radius: $height/10; color: #ffffff; }
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导入css文件 import css from './loaderTask.css'; //导入scss文件 import './loaderTask.scss'; //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = flies; return element; } //在body中添加子元素 document.body.appendChild(component()); }
webpack.config.js
//webpack配置文件 var path=require('path'); //定义一个默认模块对象 module.exports={ entry:{ idnex:"./src/index.js" }, output: { filename: "[name].task.js", path:path.resolve(__dirname,'dist') }, module: { rules: [{ test:/\.txt$/, use:'raw-loader' },{ test: /\.css/, use: ['style-loader', { loader: 'css-loader', options: { modules:true, sourceMap: true } }] },{ test: /\.scss$/, use: [ "style-loader", "css-loader", "sass-loader" ] }] }, mode: "development" };
完成后效果图如下:
2.4.9、json-loader(导入 JSON 文件)
安装:
npm i jshint-loader --save
安装成功如下:
因为webpack >= v2.0.0
,默认情况下导入JSON文件。如果您使用自定义文件扩展名,则可能仍希望使用此选项。请参见v1.0.0 - > v2.0.0迁移指南
我们不需要配置,因此我们的配置文件不需要更改即可。
src/test.json
{ "name": "tom", "age": 12 }
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导入css文件 import css from './loaderTask.css'; //导入scss文件 import './loaderTask.scss'; //导入json文件 import json from './test.json'; //导入方法1 //const json=require('./test.json'); //导入方法2 //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = "My name is"+json.name+",age is"+json.age; return element; } //在body中添加子元素 document.body.appendChild(component()); }
完成后运行结果如下:
2.4.10、url-loader
url-loader
功能类似于 file-loader
,但是在文件大小(单位 byte)低于指定的限制时,可以返回一个 DataURL(base64)。
安装:
npm install --save-dev url-loader
图片:一张jpg图片和一张gif图片
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导入css文件 import css from './loaderTask.css'; //导入scss文件 import './loaderTask.scss'; //导入json文件 import json from './test.json'; //导入方法1 //const json=require('./test.json'); //导入方法2 //导入图片 import tiger from './img/tiger.jpg'; import timg from './img/timg.gif'; //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = "My name is"+json.name+",age is"+json.age; return element; } //在body中添加子元素 document.body.appendChild(component()); //创建图片DOM var jpg=document.createElement("img"); //指定url jpg.src=tiger; //添加到网页中 document.body.appendChild(jpg); //创建图片DOM var gif=document.createElement("img"); //指定url gif.src=timg; //添加到网页中 document.body.appendChild(gif); }
webpack.config.js
//webpack配置文件 var path=require('path'); //定义一个默认模块对象 module.exports={ entry:{ idnex:"./src/index.js" }, output: { filename: "[name].task.js", path:path.resolve(__dirname,'dist') }, module: { rules: [{ test:/\.txt$/, use:'raw-loader' },{ test: /\.css/, use: ['style-loader', { loader: 'css-loader', options: { modules:true, sourceMap: true } }] },{ test: /\.scss$/, use: [ "style-loader", "css-loader", "sass-loader" ] },{ test:/\.(gif|jpe?g|png|bmp)/i, use: { loader: "url-loader" } }] }, mode: "development" };
完成后效果图如下:以base64方式加载进来
2.4.11、url-loader and file-loader
安装:
npm install --save-dev url-loader
npm install --save-dev file-loader
src/bar.js
//导入模块,获得file.txt中的文件内容,被raw-loader处理 import flies from './file.txt'; //导入css文件 import css from './loaderTask.css'; //导入scss文件 import './loaderTask.scss'; //导入json文件 import json from './test.json'; //导入方法1 //const json=require('./test.json'); //导入方法2 //导入图片 import tiger from './img/tiger.jpg'; import timg from './img/timg.gif'; //导出一个默认模块 export default function bar() { function component() { //创建了一个 h1 DOM元素 var element = document.createElement('h1'); //把文件内容写入h1中 element.innerHTML = "My name is"+json.name+",age is"+json.age; return element; } //在body中添加子元素 document.body.appendChild(component()); //创建图片DOM var jpg=document.createElement("img"); //指定url jpg.src=tiger; //添加到网页中 document.body.appendChild(jpg); //创建图片DOM var gif=document.createElement("img"); //指定url gif.src=timg; //添加到网页中 document.body.appendChild(gif); }
webpack.config.js
//webpack配置文件 var path=require('path'); //定义一个默认模块对象 module.exports={ entry:{ idnex:"./src/index.js" }, output: { filename: "[name].task.js", path:path.resolve(__dirname,'dist') }, module: { rules: [{ test:/\.txt$/, use:'raw-loader' },{ test: /\.css/, use: ['style-loader', { loader: 'css-loader', options: { modules:true, sourceMap: true } }] },{ test: /\.scss$/, use: [ "style-loader", "css-loader", "sass-loader" ] },{ test:/\.(png|jpe?g|gif|svg)(\?.*)?$/, use:{ loader: 'url-loader', options:{ limit:'1024', name:'img/[name].[hash:5].[ext]', publicPath:'dist/' } } }] }, mode: "development" };
完成效果图如下:以hash方式加进来
完成,在下告辞!!