# loader
`webpack`默认会将**js/json**文件作为模块进行加载和打包,其它如`less`、`scss`等除js外的其它模块,需要`loader`给它正确的解析或转化成为`webpack`认识的模块。
## `loader`使用
1. 通过`npm`安装需要使用的`loader`
2. 在`webpack.config.js`中的`modules`关键字下进行配置
>[success] 大部分loader我们都可以在webpack的官网中找到,并且学习对应的用法。
## 使用css
webpack将所有的文件都认为是模块所以CSS也不例外。
创建`src/index.css`
~~~
body{
background:gold;
}
~~~
**使用`css`**
在`main.js`项目入口文件 通过`import './index.css';`
~~~
import $ from "jquery"
$("ul li:even").css({background:'red'})
$("ul li:odd").css({background:'purple'})
import './index.css'
~~~
### 报错
~~~
ERROR in ./src/index.css 1:4
Module parse failed: Unexpected token (1:4)
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
> body{
| background:gold;
| }
@ ./src/main.js 5:0-20
~~~
`webpack`默认是不识别`.css`文件作为结尾的模块,需要我们通过`loader`加载器将`.css`文件进行解释成正确的模块
### css-loader
安装`npm install css-loader -D`
配置`webpack.config.js`
~~~
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin')
module.exports = {
entry:path.join(__dirname,'./src/main.js'),
output:{
path:path.join(__dirname,'./dist'),
filename:'bundle.js'
},
plugins:[
new HtmlWebpackPlugin({
template: path.join(__dirname,'./src/index.html'),
filename: 'index.html'
})
],
module:{
rules:[
{test:/\.css$/,use:['css-loader']}
]
}
}
~~~
module表示是模块的意思,rules是规则的意思,每个规则对应的都是一个对象,其中test字段表示是书写正则以哪个文件名结尾,use是一个数组,表示 当前类型文件用哪种加载器解释。
### 疑问
这次我们重新执行命令`npm start`不再报错,但是对于css的样式并未加载成功原因是为什么?缺失`style-loader`
为什么说是缺失`style-loader?`
css-loader 是将index.css正确解释 为webpack的模块,进行打包到了bundle.js,我们可以佐证,但是该样式并未成功的显示到浏览器中。
那么style-loader的作用其实就是将打包到bundle.js中的css样式输出到浏览器中,以style标签的形式显示。
![](https://img.kancloud.cn/5b/52/5b524c7fbcbd4dbe243d6b05e6c2a22a_1222x484.png)
![](https://img.kancloud.cn/87/d4/87d462a2b77a2567c0e8621f468be90e_1241x335.png)
### style-loader
安装`npm install style-loader -D`
配置`{test:/\.css$/,use:['style-loader','css-loader']}`
注意loader的加载顺序是从右向左, 即先将css文件通过css-loader 作为正确的模块进行解释,然后再通过style-loader进行显示到浏览器中。
至此CSS文件已经完成。
### 使用less文件
安装`npm install less-loader less -D`
配置:`{test:/\.less$/,use:['style-loader','css-loader','less-loader']}`
注意,我们需要借助于less编译。因为less-loader 依赖less。
### 使用sass文件
安装`npm install sass-loader node-sass -D`
配置:`{test:/\.scss$/,use:['style-loader','css-loader','sass-loader']}`
~~~
rules:[
{test:/\.css$/,use:['style-loader','css-loader']},
{test:/\.less$/,use:['style-loader','css-loader','less-loader']},
{test:/\.scss$/,use:['style-loader','css-loader','sass-loader']},
]
~~~
### 注意
对正则中的.号表示任意字符,千万小心最好把它转义一下,再来使用。
### 项目源码
`git clone https://github.com/highh5/webpack.git -b lesson-04`
## 图片处理
安装`npm install url-loader -D`
配置:`{test:/\.(jpg|jpeg|gif|png|webp)$/,use:['url-loader']},`
放置一张图片到src目录图片大小为13.54kb
:-: ![](https://img.kancloud.cn/d0/0f/d00f19c24512a946a3fbf2823542c776_200x209.png)
我们给a.scss指定body的背景是这张图片
~~~
$color:green;
body{
background: url("./avatar.jpg");
}
~~~
打开浏览器后发现图片是以base64进行编码了。什么是base64编译的图片呢?通俗的讲,图片不再像以前通过外链的形式打开,而是内嵌在网页上了。图片越大base64的编码信息越多。也就是说越大的图片会导致我们的代码越来越长。这是不是好事呢?
答案: 肯定不是很好,我们期望网页打开越快越好,如果网站当中所有的图片全是以base64来进行编码,那么会导致首页代码体积越大,那么打开速度也不会很快,相反可能会很卡。
我们一般可以让小图片使用base64进行加载,这样既能让图片快速加载,又会减少http请求。至于大图片我们一般就直接以往常的外链形式存在即可。
### 解决问题
修改loader配置项,limit表示小于后面的1000 byte即接近1kb,用base64显示。超过的限制的话通过外链来读取图片(需要安装file-loader 文件加载器)
`npm install file-loader -D`
~~~
{
test: /\.(jpg|jpeg|gif|png|webp)$/, use: [{
loader: 'url-loader',
options:{
limit:1000,
name:'[name].[hash:8].[ext]'
}
}]
},
~~~
最终图片被正确解释出来
~~~
body {
background: url(avatar.9d23d463.jpg);
}
~~~
# ES6 转 ES5
## 安装
`npm install babel-core babel-loader@7.1.5 babel-plugin-transform-runtime babel-preset-env babel-preset-stage-0 -D`
## 配置loader
~~~
{test:/\.js/,use:['babel-loader'],exclude:/node_modules/}
~~~
exclude表示排除掉 node\_modules下载的依赖项。这样可以加速网站开发,而且我们也只需要对我们的项目src源文件进行编译即可。
## 新增.babelrc文件
~~~
{
"presets":[“env","stage-0"],
"plugins":["transform-runtime"]
}
~~~
## 修改main.js使用es6语法
~~~
class Person {
constructor(){
}
}
var p = new Person();
~~~
## 执行命令编译
`npm start`
编译后的结果接近在1335行
~~~
\n\n var Person = function Person() {\n (0, _classCallCheck3.default)(this, Person);\n};\n\nvar p = new Person();\n\n
~~~
**至此关于webpack的基本配置已经到这里。**
## 项目源码
`git clone https://github.com/highh5/webpack.git -b lesson-05`
## 解释
`babel-present-env` 仅仅包括 b`abel-present-2015`、2016、2017,不包括:`babel-stage-x`,也不包括 `babel-polyfill`
`babel-present-env` 仅仅转换 新版的语法 如:箭头函数,并不转换新版api 如:Array.include转换新版api及抹平浏览器之间的差异(兼容ie)需要 babel-polyfill
`babel-polyfill`会污染全局,比较暴力。而`babel-plugin-transfrom-runtime`是哪里需要就给哪里转换。
`babel-plugin-transform-runtime`主要做了一下三件事:
当你使用 `generators/async`函数时,自动引入`babel-runtime/regenerator` (使用 regenerator 运行时而不会污染当前环境) 。
自动引入`babel-runtime/core-js`并映射 ES6 静态方法和内置插件(实现polyfill的功能且无全局污染,但是实例方法无法正常使用,如`“foobar”.includes(“foo”) )`。
移除内联的`Babel helper` 并使用模块`babel-runtime/helpers` 代替(提取babel转换语法的代码)。
## 参考文档
[https://segmentfault.com/a/1190000010468759](https://segmentfault.com/a/1190000010468759)