Webpack 资源管理

资源管理

? 提示:

1、版本问题

本文基于 webpack 2.x 版本。webpack 2.x 相比 webpack 1.x 有重大改变。所以,如果你的项目中已使用了 webpack 1.x ,本教程的示例将不适用,请慎重。 如果铁了心要升级 webpack ,请参考 webpack 官方文档 - 从 v1 迁移到 v2

2、阅读建议

阅读本文前,建议先阅读 Webpack 概念

webpack 的优势

webpack 最重要的功能就是资源管理。

JavaScript 世界已有好几个有名的资源管理工具,webpack 有什么独到之处呢?

webpack 出现之前,前端开发人员会使用 gruntgulp 等工具来处理这些 web 资源,如样式文件(例如 .css.less.sass),图片(例如 .png.jpg.svg),字体(例如 .woff.woff2.eot)和数据(例如 .json.xml.csv)等,并将它们从 /src 文件夹移动到 /dist 或 /build 目录中。

而 webpack 从 entry(入口) 开始,访问应用程序,并动态打包(dynamically bundle)所有依赖项。这是极好的创举,因为现在每个模块都可以明确表述它自身的依赖,这可以避免打包未使用的模块。

Loader

Loader(加载器) 用于对模块的源代码进行转换。

使用加载器一般遵循几步:

  1. 安装加载器
  2. 配置 Loader
  3. 引用资源文件

安装加载器

根据需要加载的资源文件,选择下载对应的加载器。

$ npm install --save-dev css-loader

更多 webpack 可用Loader 请查看:webpack loaders

配置 Loader

​⚠️ 注意: webpack 2.x 版本的 Loader 配置和 webpack 1.x 版本差别很大。

Loader 在 webpack.config.js 文件的 module 属性中配置。

资源类型对应单一加载器

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

资源类型对应多个加载器

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

加载器含配置选项

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

引用资源文件

完成上两步后,就可以在 JavaScript 中使用 importrequire 关键字引用相应类型资源文件。

import './index.css';
require('./index.css');

Plugin

Plugin(插件) 用于解决 Loader 无法解决的问题,它是 Loader 的辅助。

由于 plugin 可以携带参数/选项,你必须在 wepback 配置中,向 plugins 属性传入 new 实例。

安装插件

webpack 自身包含了一些常用插件,你可以通过 webpack 来引用。除此之外的插件,使用前需要安装

$ npm install --save-dev html-webpack-plugin OpenBrowserPlugin

更多 webpack Plugins 可以查看: webpack plugins

配置 Plugin

const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const OpenBrowserPlugin = require('open-browser-webpack-plugin');

module.exports = {
  // 附加插件列表
  plugins: [
    // 压缩 js 插件
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    }),

    // 用于简化 HTML 文件(index.html)的创建,提供访问 bundle 的服务。
    new HtmlWebpackPlugin({
      title: "react-step-by-step",
      template: "./index.html"
    }),

    // 自动打开浏览器
    new OpenBrowserPlugin({
      url: "http://localhost:8080"
    })
  ]
};

加载资源专题

加载 React

很多浏览器并不识别 React 语法,为了让浏览器支持,你需要使用 babel-loader 解释器来转义 React 语法为普通的 Javascript 语法。

⚠️ 注意: 官方推荐 babel-loader 和 webpack 的对应版本 webpack 1.x | babel-loader <= 6.x webpack 2.x | babel-loader >= 7.x (推荐)(^6.2.10 也可以运行,但会有不赞成的警告(deprecation warnings))

首先,安装需要使用的库:

$ npm install --save-dev babel-loader babel-preset-es2015 babel-preset-react

babel-preset-xxx 表示你希望转义的语法。

webpack.config.js 中的模块配置如下:

// 关于模块配置
module: {

  // 模块规则(配置 loader、解析器等选项)
  rules: [
    // 这里是匹配条件,每个选项都接收一个正则表达式或字符串
    // test 和 include 具有相同的作用,都是必须匹配选项
    // exclude 是必不匹配选项(优先于 test 和 include)
    // 最佳实践:
    // - 只在 test 和 文件名匹配 中使用正则表达式
    // - 在 include 和 exclude 中使用绝对路径数组
    // - 尽量避免 exclude,更倾向于使用 include
    {
      // 语义解释器,将 js/jsx 文件中的 es2015/react 语法自动转为浏览器可识别的 Javascript 语法
      test: /\.jsx?$/,
      include: path.resolve(__dirname, "app"),

      // 应该应用的 loader,它相对上下文解析
      // 为了更清晰,`-loader` 后缀在 webpack 2 中不再是可选的
      // 查看 webpack 1 升级指南。
      loader: "babel-loader",

      // loader 的可选项
      options: {
        presets: ["es2015", "react"]
      },
    },
  ]
},

​? 示例DEMO04: (DEMO / SOURCE)

加载 CSS

为了从 JavaScript 模块中 import 一个 CSS 文件,你只需要在 module 中安装并添加 style-loader 和 css-loader

$ npm install --save-dev style-loader css-loader

webpack.config.js

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

好了,此时你就可以在代码中通过 import './style.css' 的方式引入 CSS 文件。

其余,加载 less,sass 等样式文件也是大同小异,不一一细说。

? 示例DEMO06: (DEMO / SOURCE)

加载图片

如何打包、加载图片呢?你可以使用 file-loader来指定要加载的图片。

$ npm install --save-dev file-loader

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.(png|svg|jpg|gif)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  },
  //...
}

然后,你可以通过 import imgBig from './lion.png' 的方式引入图片。例:

import React from 'react';
import imgBig from './lion.png';

class Welcome extends React.PureComponent {
  render() {
    return (
      <div>
        <h1>Hello, {this.props.name}</h1>
        <img src={imgBig} />
      </div>
    );
  }
}
export default Welcome;

压缩图片

这还不算完,日常开发中,经常会遇到有些图片文件过大的问题,这会影响你的 app 的加载速度。webpack 提供了压缩图片的方法帮你解决图片大的问题。

首先,你需要安装 image-webpack-loader

$ npm i --save-dev image-webpack-loader

接下来,修改 webpack.config.js

{
  // 图片加载 + 图片压缩
  test: /\.(png|svg|jpg|gif)$/,
  loaders: [
    "file-loader",
    {
      loader: "image-webpack-loader",
      query: {
        progressive: true,
        pngquant: {
          quality: "65-90",
          speed: 4
        }
      }
    }
  ]
}

? 示例DEMO07: (DEMO / SOURCE)

加载字体

那么,像字体这样的其他资源如何处理呢?file-loader 和 url-loader 可以接收并加载任何文件,然后将其输出到构建目录。这就是说,我们可以将它们用于任何类型的文件,包括字体:

webpack.config.js

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.(woff|woff2|eot|ttf|svg)$/,
        use: [
          'file-loader'
        ]
      }
    ]
  },
  //...
}

一切就绪后,你可以在 css 文件中这样引入字体:

@font-face {
  font-family: 'MyDiyFont';
  src: url('./font/iconfont.eot'); /* IE9*/
  src: url('./font/iconfont.eot?#iefix') format('embedded-opentype'), /* IE6-IE8 */
  url('./font/iconfont.woff') format('woff'), /* chrome、firefox */
  url('./font/iconfont.ttf') format('truetype'), /* chrome、firefox、opera、Safari, Android, iOS 4.2+*/
  url('./font/iconfont.svg#iconfont') format('svg'); /* iOS 4.1- */
}

h1 {
  font-family: 'MyDiyFont';
  font-size: 24px;
}

p {
  font-family: 'MyDiyFont';
  font-size: 18px;
}

然后,相对路径,会被替换为构建目录中的完整路径/文件名。

? 示例DEMO08: (DEMO / SOURCE)

Webpack 系列教程

欢迎阅读其它内容:

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏向治洪

React Native导航器之react-navigation使用

在上一节Navigation组件,我们使用系统提供的导航组件做了一个跳转的例子,不过其实战能力不强,这里推荐一个超牛逼的第三方库:react-navigatio...

1.5K7
来自专栏Youngxj

[软件]图片中隐藏你想藏的文件

1252
来自专栏Java与Android技术栈

多个语言项目发布JCenter仓库的小结

我在 JCenter 上发布过 Java、Android、Kotlin 的项目已经有数十个了。踩坑无数,所以写下这篇文章,作为记录和总结。

792
来自专栏.NET技术

.net core实践系列之SSO-同域实现

SSO的系列还是以.Net Core作为实践例子与大家分享,SSO在Web方面复杂度分同域与跨域。本篇先分享同域的设计与实现,跨域将在下篇与大家分享。

1271
来自专栏玄魂工作室

textarea的中文输入判断与搜狗输入法的特殊行为

虽然要讲解的知识点是通用的,但是还是要介绍下我的应用场景和测试环境。 0.1 应用场景和测试环境 我的应用是一块使用Html Canvas开发的黑板,在黑板上实...

33411
来自专栏技术博客

比NotePad++更好的文本代码(C#)编辑器Sublime Text

 前两天在博客园看到@晴天猪的博客发表的关于他使用的代码编辑器,自己索性试了一下,果断好用,自己也来记录一下。以便以后配置使用。接下来我配置的主要是简单的编译C...

1582
来自专栏前端知识分享

第132天:移动web端-rem布局(进阶)

      该方案使用相当简单,把下面这段已压缩过的 原生JS(仅1kb,源码已在文章底部更新,2017/5/3) 放到 HTML 的 head 标签中即可(注...

753
来自专栏草根专栏

使用Identity Server 4建立Authorization Server (5)

之前的配置都是在内存中, 下面将如何把这些数据存储到Sql Server数据库, 这样更适合生产环境. 这部分基本完全参考官方文档: https://ident...

3295
来自专栏blackheart的专栏

[Cake] 0.C#Make自动化构建-简介

0. Cake是什么? Cake是C# Make的缩写,是一个基于C# DSL的自动化构建系统。它可以用来编译代码,复制文件以及文件夹,运行单元测试,压缩文件以...

2285
来自专栏逸鹏说道

NET跨平台:在Ubuntu下搭建ASP.NET 5开发环境

0x00 写在前面的废话 年底这段时间实在太忙了,各种事情都凑在这个时候,没时间去学习自己感兴趣的东西,所以博客也好就没写了。最近工作上有个小功能要做成Web应...

2513

扫码关注云+社区