基础:入口entry

127 阅读4分钟

webpack的入口entry是个很简单的概念,就是为了定义webpack从哪里开始识别文件进行编译,写在webpack.config.js文件中

就如过韩梅梅叫了一家搬家公司来帮自己打包搬家,搬家小哥总要先问问,你家门在哪条街哪一户。一样的道理。

单个入口

从概念那一节我们举出的例子,能看出可以直接通过entry来进行定义。例如这样

module.exports = {
  entry: './path/to/my/entry/file.js',
};

实际上这是一种简写方式,完整些来应该是:

module.exports = {
  entry: {
    main: './path/to/my/entry/file.js',
  },
};

这种entry简化的方式只是为了方便用户。

如同韩梅梅如果只是搬自己一户,完全可以只告诉小哥我就在302户就可以了

但是这种方式的缺点也很明显,扩展性不够,只能够配置main属性,无法配置名称等多种属性。

当然webpack也为了方便,提供了entry的路径数组模式,如果就是不需要额外配置,那就直接写就好了。

module.exports = {
  entry: ['./src/file_1.js', './src/file_2.js'],
  output: {
    filename: 'bundle.js',
  },
};

这就如同韩梅梅除了搬自己,也想把对面301户自己爸爸妈妈的东西也一并搬走,她就要告诉搬家公司entry:[301, 302]

对象语法

这种方式就能够实现各种配置项,给搬家公司提出各种要求,当然同样的,对应的复杂度就高起来了。每一个入口就可以认为是一个chunk

name描述
dependOn当前依赖的入口
filename指定输出的文件名称
import启动需加载的模块
library为entry创建一个library
runtime运行时 chunk 的名字,设置了就会创建一个新的chunk
publicPath当该入口的输出文件在浏览器中被引用时,为它们指定一个公共 URL 地址

这么一看好像非常的复杂,也很难理解,实际上我们只需要简单理解就可以了。但是我给大家举个例子,还是那个熟悉的韩梅梅搬家。

module.exports = {
  entry: {
    a2: './301',
    b2: {
      dependOn: '302',
      import: './basement',
      filename: '302box',
      publicPath: 'https://cdn.example.com/car2/'
    },
  },
};

韩梅梅首先告诉搬家公司,帮我把301的直接搬走,但是302的搬家就有要求了。 首先通过dependOn告诉搬家公司(webpack)我要把302搬走,然后import告诉他们依赖在地下室basement放置了很多盒子要用来搬家打包。打包完的内容也就是我们称之为输出的文件(搬家包裹)名称定义为302box。最后publicPath定义了我们最后怎么找到这些打包好的盒子。也就是说我们能在car2这辆车里找到我们打包好的盒子。

这么一看是不是其实也没什么复杂的,就是定义了如何来对一个(或多个)文件进行打包。

实战

分离app和vendor(第三方库)入口

我们在加载页面的过程中可能需要依赖Bootrap、jQuery等等第三方库来完成页面渲染。而这些库基本上不可也无需修改,因此我们可以把这部分内容打包进单独的文件,例如打包进vendor文件夹中。

这样做的好处是什么呢?

浏览器可以单独把第三方库打包,浏览器就可以独立缓存vendor文件,从而降低加载时间。

那么如何做呢

  1. 新建webpack.config.js。定义了两个入口,app作为主入口,vendor用来定义第三方库
module.exports = {
  entry: {
    main: './src/app.js',
    vendor: './src/vendor.js',
  },
};
  1. 新建webpack.prod.js。定义线上production环境打包
module.exports = {
  output: {
    filename: '[name].[contenthash].bundle.js',
  },
};
  1. 新建webpack.dev.js。定义本地dev开发环境打包
module.exports = {
  output: {
    filename: '[name].bundle.js',
  },
};

题外话,为什么prod和dev的文件定义不同?多出的文件定义为[contenthash],如果编译的文件内容没有变化,那么contenthash输出的随机值也不会变化,依然可以使用浏览器上一次缓存的内容。同时这个随机指也可以用来保证线上环境资源的更新,不至于造成新资源没有在家成功的情况。