合规国际互联网加速 OSASE为企业客户提供高速稳定SD-WAN国际加速解决方案。 广告
# 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)