细说webpack 4. webpack的常见配置(上)

你们好!我是萝卜,这一章跟你们介绍 webpack 4 常见的配置。javascript

webpack.config.js配置文件

webpack 是可配置的模块打包工具,能够经过修改 webpack.config.js 的配置文件对 webpack 进行配置,webpack 的配置文件遵循 Nodejs 的 CommonJS 模块规范,可经过 require() 语法导入其余文件或者使用 Nodejs 内置的模块,其实 webpack.config.js 是一个 Nodejs 的模块。css

一个简单的 webpack.config.js 例子

const path = require('path');

module.exports = {
  mode: 'development',
  entry: './entry.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'entry.bundle.js'
  }
};

上面例子中使用CommonJS的 require 引入 Nodejs 内置的 path 模块,而后经过 module.exports 将 webpack 的配置导出。html

Tips: webpack 的配置是一个 Nodejs 模块,并非 JSON 对象。

webpack 配置支持多种语言

webpack 不只仅支持 js 配置,还支持 TypeScript 、CoffeeScript 甚至 JSX 语法的配置,可是不论使用什么语言,核心配置项是相同的,只不过是语法不一样。除了配置文件的语法多样以外,对于配置的类型也是多样的,最多见的是做为一个对象来使用,除了对象,webpack 还支持函数、Promise 和多配置数组。前端

如何使用 webpack.config.js 配置文件

默认状况下,webpack 会查找执行目录下的 webpack.config.js 做为配置,若是须要指定某个配置文件,可使用命令:java

npx webpack --config webpack.config.js

或者在项目目录下运行node

node ./node_modules/webpack/bin/webpack --config webpack.config.js

webpack 的核心概念

虽然 webpack 的功能强大且配置项多,可是只要理解了如下的几个核心概念,就能随心应手的使用它,webpack 有如下几个核心概念:webpack

  • entry: 项目入口,webpack 执行构建的第一步将从 entry 开始,可抽象成输入。
  • module: 模块,在 webpack中一切皆模块,一个模块对应一个文件,模块不局限于js,也能够是 css、图片等。webpack 会从配置文件的 entry开始递归找出全部依赖的模块。
  • chunk: 代码块,一个 chunk 能够由多个模块组合而成,用于代码合并与分割。
  • loader: 模块转换器,用于将模块的原内容按照需求转换成新内容。
  • plugin: 扩展插件,在 webpack 构建流程中的特定时机注入扩展逻辑,能够完成 loader 完不成的任务。
  • output: 输出结果,在 webpack 通过一系列处理并得出最终想要的代码后输出结果。

webpack 的入口(entry)和输出(output)

webpack 是一个模块打包工具,可以从一个须要处理的 javascript 文件开始,构建一个依赖关系图(dependency graph),该图映射到了项目中每一个模块,而后将这个依赖关系图输出到一个或者多个 bundle 中。
webpack 是从指定的入口文件(entry)开始,通过加工处理,最终按照 output 输出固定内容的 bundle。而这个加工处理的过程,就用到了 loader 和 plugin 两个工具,loader 是源代码的处理器,plugin 解决的是 loader 处理不了的事情。web

entry 入口

webpack 的 entry 支持多种类型,包括字符串、对象、数组。从做用上说,包括单文件入口和多文件入口两种方式。数组

单文件入口

module.exports = {
  entry: 'path/index.js'
}

// 使用对象的方式
module.exports = {
  entry: {
    main: 'path/index.js'
  }
}

单文件入口能够快速建立一个只有单一文件入口的状况,可是相对简单,在扩展配置时灵活性较低。浏览器

module.exports = {
  mode: 'development',
  entry: ['./src/index1.js', './src/index2.js']
}

不管是字符串仍是字符串数组的 entry ,实际上都是只有一个入口,可是在打包产出上会有差别:
若是直接是 string 的形式,那么 webpack 就是直接把该 string 指定的模块做为入口模块。
若是是数组的形式,那么 webpack 会自动生成另外一个入口模块,并将数组中的每一个元素指定的模块加载进来,并将最后一个模块的 module.exports 做为入口模块的 module.exports 导出。

多文件入口

多文件入口是使用对象语法来经过支持多个 entry ,多文件入口的对象语法相对于单文件入口,具备更高的灵活性,例如多页应用、页面模块化分离优化。

module.exports = {
  entry: {
    home: 'path/home.js',
    search: 'path/search.js',
    list: 'path/list.js'
  }
}

上面的语法将 entry 分红了 3 个独立的入口文件,这样会打包出来三个对应的 bundle。

Tips: 对于一个 html 页面,我推荐只用一个 entry ,经过统一入口,解析出来的依赖关系更方便管理和维护。

output 输出

webpack 的 output 是指定了 entry 对应文件编译打包后的输出 bundle 。output 的经常使用属性是:

  • path: 规定了打包后输出的 bundle 的存放路径。
  • filename: 这个是 bundle 的名称。
  • publicPath: 指定了一个在浏览器中被引用的 URL 地址。
Tips: 当不指定 output 的时候,默认输出到 dist/main.js,即 output.path 是
dist,output.filename 是 main。

一个 webpack 的配置,能够包含多个 entry ,可是只能有一个 output 。对于不一样的 entry 能够经过 output.filename 占位符来区分。

module.exports = {
  entry: {
    home: 'path/home.js',
    search: 'path/search.js',
    list: 'path/list.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}

其中 [name] 就是占位符,它对应的是 entry 的 key (home、search、list)。
目前 webpack 支持的占位符有:

  • [hash] 模块标识符的 hash
  • [chunkhash] chunk 内容的 hash
  • [name] 模块名称
  • [id] 模块标识符
  • [query] 模块的 query,例如,文件名 ? 后面的字符串
  • [function] 一个 return 出一个 string 做为 filename 的函数

[hash] 和 [chunkhash] 的长度可使用[hash:16] (默认为 20) 来指定,或者经过指定output.hashDigestLength 在全局配置长度,那么他们之间的区别是什么?

  • [hash]:是整个项目的 hash 值,其根据每次编译内容计算获得,每次编译以后都会生成新的 hash,即修改任何文件都会致使全部文件的 hash 发生改变;在一个项目中虽然入口不一样,可是 hash 是相同的;hash 没法实现前端静态资源在浏览器上长缓存,这时候应该使用 chunkhash;
  • [chunkhash] :根据不一样的入口文件(entry)进行依赖文件解析,构建对应的 chunk,生成相应的 hash;只要组成
    entry 的模块文件没有变化,则对应的 hash
    也是不变的,因此通常项目优化时,会将公共库代码拆分到一块儿,由于公共库代码变更较少的,使用 chunkhash 能够发挥最长缓存的做用;
  • [contenthash]:使用 chunkhash 存在一个问题,当在一个 JS 文件中引入了 CSS 文件,编译后它们的 hash
    是相同的。并且,只要 JS 文件内容发生改变,与其关联的 CSS 文件 hash 也会改变,针对这种状况,能够把 CSS 从 JS 中使用
    mini-css-extract-plugin 或 extract-text-webpack-plugin 抽离出来并使用
    contenthash。

[hash]、[chunkhash] 和 [contenthash] 都支持 [xxx:length] 语法。

Tips: 占位符是能够组合使用的,例如 [name]-[hash:8]

output.publicPath

咱们构建出的静态资源文件都是经过 <script> 或者 <link> 标签进行加载的,并且这些静态资源文件都是须要部署在静态资源服务器或者 CDN 上,那么如何将这些静态资源文件放在不一样的域名或者 CDN 上面呢?这时就要用到 output.publicPath 来进行配置:

module.exports = {
  output: {
    filename: '[name]_[chunkhash:8].js',
    publicPath: 'https://cdn.ezample.com/assets/'
  }
}

则输出:

<script src="https://cdn.ezample.com/assets/a_456456456.js"></script>

output.library 与 output.libraryTarget

咱们在实际开发中老是须要去打包一些供团队其余小伙伴使用的库,这时就须要用到 output.library 与 output.libraryTarget,output.library 用来指定库的名称,output.libraryTarget 用来指定打包出来的规范,好比:commonjs二、amd、umd2等。

小结

这一章咱们从 webpack 的配置文件 webpack.config.js 基本语法入手,讲解了配置的基本用法以及 mode、context、entry、output基础概念,但愿能给你们带来一些帮助,若是想了解更多,请持续关注个人文章。

相关文章
相关标签/搜索