前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Webpack(二):使用 loader

Webpack(二):使用 loader

作者头像
Chor
发布2019-11-07 17:26:51
9070
发布2019-11-07 17:26:51
举报
文章被收录于专栏:前端之旅前端之旅前端之旅

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 构建的,所以暂时先跟着讲师的步伐吧 =。=)

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2019-10-20,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. loader 安装和配置
  • 2. 样式处理
    • 2.1 css-loader 和 style-loader
      • 2.1 less-loader
      • 3. 图片打包
        • 2.1 css 引用
          • 2.2 js 引用
          • 4. Babel 转译
          • 5. 集成 Vue
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档