Webpack(二):使用 loader

Webpack 提倡一切皆模块,所有类型的文件(css、图片等)都可以经过 loader 处理变成我们可加载的模块。

1. loader 安装和配置

安装 loader 统一方式是 npm insatll xxx-loader --save -dev

-dev 表示开发时依赖。

webpack.config.js 基本配置方式:

module.exports = {
  entry: ...,
  output:{...},
  module:{
    rules:[
      {
        test: ...,
        use:['xxx-loader','xxx-loader',...]
      },
      {...},
      {...},
    ]
  }
}

2. 样式处理

2.1 css-loader 和 style-loader

css-loader 通过 npm 安装,但是要把样式真正挂载到 dom 上,还需要安装 style-loader

通过 webpack.conifg.js 配置 css-loader 和 style-loader。注意 webpack 是从右向左读取的,书写顺序有要求。

module:{
  rules:[
    {
      test: /\.css$/,
      use:['style-loader','css-loader']
    }
  ]
}

2.1 less-loader

同样的,还可以使用 less-loader:

module:{
  rules:[
    {
      test: /\.css$/,
      use:['style-loader','css-loader']
    },
    {
      test:/\.less$/,
      use:[{
        loader:"style-loader"
      },{
        loader:"css-loader"
      },{
        loader:"less-loader"
      }]
    }
  ]
}

从 npm 3.x 开始,less 不会再随着 less-loader 的安装而自动给你安装,所以我们需要手动安装 less,也就是完整命令:npm install less less-loader --save -dev,否则后续打包会报错。

3. 图片打包

和图片打包相关的两个 loader ,一个是 url-loader,一个是 file-loader。

如果图片较多,会发送很多 http 请求,降低页面性能。因此,url-loader 会将引入的图片编码,生成 base64 的 dataURL —— 相当于把图片数据翻译成一串字符,再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。

当然,如果图片较大,编码会消耗性能,打包文件体积也会变大,因此 url-loader 提供了一个 limit 参数(一般是8kb),小于 limit 的图片依然被转为 DataURL;大于 limit 的图片则调用 file-loader 进行copy,并输出到 dist 文件夹中。 虽说 url-loader 封装了 file-loader,但实测如果不额外安装 file-loader 的话,在图片体积较大时打包还是会报错的,因此两个都要安装。

下面通过例子说明在 CSS 或者 JS 中使用图片时,loader 是如何处理的。

2.1 css 引用

这里我们在 src 下新建 img 文件夹,里面放 test1.jpg 和 tets2.jpg,一张大于8kb,一张小于8kb。在前面的 index.css文件中,我们像往常一样使用图片作为背景:

div{
  width:100px;
  height:200px;
  background:url("../img/test1.jpg");
}

之后打包发现报错,所以我们安装 url-loader,再次打包。浏览器查看:

会发现图片可以正常引用了,而且是以 dataURL 的形式引用的。

接着测试大于8kb的图片(修改上面代码为 test2.jpg )。这时,如果直接打包会报错提示缺少 file-loader,所以我们这里安装一下 file-loader。

再次打包,虽说这次不报错了,但是我们发现浏览器里图片没有显示出来。看一下控制台:

可以看到,路径是直接引用的图片名字,同时会看到 dist 文件夹下输出了原始图片的副本。也就是说,其实这时候 webpack 认为我们的 index.html文件在 dist 文件夹中,所以选择了这样的路径引用,但其实我们的 index.html文件在外层。同时,我们也不希望直接输出在 dist 文件夹下,最好是里面还有一个 img 文件夹,所以我们先来 webpack.config.js 配置一下:

{
  test: /\.(png|jpg|gif|jpeg)$/,
  use:[{
    loader:"url-loader",
    options:{
      limit:8192,
      outputPath:'img'
    }
  }]
}

这里就设置了图片的输出路径,另外,图片默认以 32 位 hash 命名,这样太长了,而且也不知道具体是哪张图片,所以我们顺便配置一下图片命名规则:

{
  test: /\.(png|jpg|gif|jpeg)$/,
  use:[{
    loader:"url-loader",
    options:{
      limit:8192,
      outputPath:'img',
      name:'[name].[hash:8].[ext]'
    }
  }]
}

再次打包,打开控制台:

可以看到,命名正确了,文件输出方式也正确了(dist 下多出一个 img 文件夹),但是图片路径还是错的,所以不显示图片。我们接着来配置一下图片路径。 我们前面说过,webpack 认为 index.html 在 dist 文件夹中,所以才会直接通过图片名字引用图片。那么 index.html 实际上是在 dist 文件夹外面的,对于 index.html 来说,它就要通过 ./dist/img 才能顺利找到图片,也就是说,我们可以在原本路径(图片名)的基础上加一个固定前缀(./dist/img),使之正确指向图片位置(./dist/img/图片名)。

publicPath 正是可以用来做这件事的:

{
  test: /\.(png|jpg|gif|jpeg)$/,
  use:[{
    loader:"url-loader",
    options:{
      limit:8192,
      outputPath:'img',
      publicPath:'./dist/img',
      name:'[name].[hash:8].[ext]'
    }
  }]
}

publicPath 会给使用了相对路径引用的图片加上统一前缀。比如我们的图片路径一开始是 img/test2.95a05a82.jpg,那么使用了 publicPath 后,图片路径就变成 ./dist/img/test2.95a05a82.jpg。通常可以给 publicPath 配置一个 cdn 地址前缀,比如 https://xxx.cdn.com,上线的时候图片就都统一使用 cdn 地址了。

那么配置好后再次打包,浏览器查看:

路径正常,而且图片也正常显示了。

另外,我们也可以选择给 output.publicPath 配置 ./dist/,这样的话不止是图片,所有使用相对路径引用的静态资源都会加上这个前缀了。不过要注意,这个前缀需要加一个 /,而图片的 publicPath 是不需要的。

2.2 js 引用

js 中引用图片需要使用 require,举个例子:

// module2.js

// require 拿到图片路径字符串
var img = require('../img/test2.jpg');
// 模板字符串构建 img 标签
export var demo = `<img src="${img}"/>`
// main.js
import demo from './js/module2.js';
document.body.innerHTML = demo;

只管根据图片和 module2.js 的路径关系正常引入图片即可,后面路径会被正确替换。 如果我们之前没有配置 publicPath 的话,会发现打包后的路径是 img/test2.95a05a82.jpg,也即 index.html 依然被当作是位于 dist 文件夹下的。因为我们前面配置了,所以这里路径是正确的,最后可以正常显示图片:

4. Babel 转译

命令行安装:

npm install --save -dev babel-loader@7 babel-core babel-preset-es2015

配置 webpack.config.js

module:{
    rules:[
        {...},
        {...},
        {
            test:/\.js$/,
            exclude:/(node_modules|bower_components)/,
            use:{
                loader:'babel-loader',
                options:{
                    presets:['es2015']
                }
            }
        }
    ]
}

exclude:/(node_modules|bower_components)/ 表示不转译 node_modules 文件夹中的 js 。

babel-loader 的预设:

  • babel-preset-es2015babel-preset-es2016 等:支持不同版本的ECMAScript规范;
  • babel-preset-latest: 支持现有所有 ECMAScript 版本的新特性,包括处于stage 4里的特性(已经确定的规范,将被添加到下个年度的)。
  • babel-preset-env:但很多时候我们需要更灵活的 preset —— 比如大部分浏览器已经支持了 ES6 的某个特性,那么对于这个特性我们其实是不必去转译的,但前面所说的那些 preset 会一概转译。所以这里还提供了 babel-preset-env,它可以根据我们指定的目标环境(比如某个版本的浏览器)来选择它不支持的特性进行转译。

5. 集成 Vue

注意这不是一个开发时依赖:

npm install vue@2.5.21 --save

如果遇到这个报错:

You are using the runtime-only build of Vue where the template compiler is not available. Either pre-compile the templates into render functions, or use the compiler-included build.

这是因为 Vue 有两个版本:

  • runtime-only
  • runtime-compiler

其中,runtime-only 版本无法编译模板,要么用 render 函数,要么修改 webpack.config.js 配置改用其它版本。这里我们先选择后者:

module.exports = {
    entry: ...,
    output: {...},
    module: {...},
    resolve:{
        alias:{
             'vue$':'vue/dist/vue.esm.js'  // 指定版本
        }
    }
}

另外,webpack 还需要分别借助 vue-loader 和 vue-template-compiler 去加载和解析 .vue 文件:

npm install vue-loader@13.0.0 vue-template-compiler@2.5.21 --save -dev

之后我们就可以编写单文件组件了( 使用 vscode 的话强烈建议安装 vetur 插件)。

Note

因为我们安装的 vue 版本是 vue@2.5.21,所以这里的 vue-loader 和 vue-template-compiler 要注意版本对应问题,总之报错信息也写得很清楚了。

(要说为什么用这么低版本的 vue,因为视频里的项目也是用低版本 Vue 构建的,所以暂时先跟着讲师的步伐吧 =。=)

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏DotNet程序园

Asp.NET Core 轻松学-项目目录和文件作用介绍

    上一章介绍了 Asp.Net Core 的前世今生,并创建了一个控制台项目编译并运行成功,本章的内容介绍 .NETCore 的各种常用命令、Asp.Ne...

9010
来自专栏python编程军火库

5分钟面试指南(第十五篇 json 你值得拥有)

本部分我们会为大家提供一些python初级工程师在面试过程中遇到的常见的面试题目,期望达到的效果:

8820
来自专栏Flutter笔记

Flutter实战 | 从 0 搭建「网易云音乐」APP(三、每日推荐、推荐歌单)

本系列可能会伴随大家很长时间,这里我会从0开始搭建一个「网易云音乐」的APP出来。

16720
来自专栏python编程军火库

第二篇 爬虫技术之HTML

hello,大家好今天我们继续分享爬虫的相关技术,今天我们分享的是html的基础知识。

6610
来自专栏算法channel

这是我的10分钟 js 入门笔记

别问做算法和数据分析的,怎么还学js. 工作了需要啥都得学,还得快。这就是互联网,适者生存,劣者淘汰。

7920
来自专栏Creator星球游戏开发社区

Cocos Creator 3D 物理模块介绍

为了让游戏开发更加简单、友好和高效,Cocos Creator 3D 在研习和摸索中设计了一套比较基础的物理组件,并且还在持续完善中。尽管当前的组件功能还十分有...

24810
来自专栏业余草

Java 必会10大的经典算法

原文链接:https://github.com/hustcc/JS-Sorting-Algorithm

13410
来自专栏sofu456

gulp&&webpack打包

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

11420
来自专栏叉叉敌

微信小程序 wxs 使用正则替换字符串

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。 ...

44930
来自专栏算法channel

必备神器:webpack使用入门

昨天,写了入门javascript的一篇文章:这是我的10分钟 js 入门笔记,老铁给我们的建议,js非常有用,具体请看下面:

10010

扫码关注云+社区

领取腾讯云代金券

年度创作总结 领取年终奖励