Webpack上手指北

近几年,打包构建工具层出不穷,前有Grunt、Gulp,后有Webpack、Rollup等,它们各有优点,均受到部分开发者的欢迎,本文聊聊Webpack的使用。css

模块化

不管是新工具仍是新技术,都是为了解决问题而存在,那么构建工具解决什么问题呢?html

众所周知,最初的网页十分简单,没有多少交互,代码量也少,但随着技术的发展,JavaScript已经不只仅用来实现简单的表单提交等功能,引入多个js文件到页面中成为常态,但这种作法有不少缺点:前端

1)须要手动维护文件的加载顺序。且多个js之间一般有依赖关系,难以清晰分辨谁依赖了谁。vue

2)每个<script>标签都须要向服务器发送请求,过多的请求会严重拖慢渲染速度。node

3)每一个<script>标签都暴露在全局做用域,若是没有任何处理而直接在代码中进行变量或函数声明,就会形成全局污染。webpack

模块化解决了这些问题:web

  • 经过分离模块,导入和导出,能够清晰地看到模块间的依赖关系。npm

  • 借助工具进行打包,页面中只须要加载合并后的资源文件,减小了网络开销。json

  • 模块之间做用域隔离,彼此不会有命名冲突。数组

使用Webpack的理由

打包工具众多,为何选择Webpack?Webpack具有如下几点优点。

1)默认支持多种模块标准,包括AMD、CommonJS,以及最新的ES6模块。这对于某些同时使用多种模块标准的工程很是有用,Webpack会帮咱们处理好不一样类型模块之间的依赖关系。

2)完备的代码分割解决方案。能够分割打包后的资源,首屏只加载必要的部分,不重要的放到后面动态加载。这对于体积较大的应用尤其重要,可有效减少资源体积,提高首页渲染速度。

3)能够处理各类类型的资源。除JavaScript之外,还能够处理样式、模板、图片等,而开发者须要作的仅仅是导入它们。好比你能够从JavaScript文件导入一个CSS或者PNG,而这一切最终均可以由下面讲到的loader来处理。

4)庞大的社区支持。除了Webpack核心库之外,还有无数开发者为它编写周边插件和工具,大多数的需求你均可以找到现有解决方案。

配置与方法

看看怎么使用。

依赖Node,这几乎是前端开发的标配,很少说。

学习一种东西的时候最怕看到各类陌生概念,这里先捋一捋。

为了便于理解,按照工做流程的阶段:

entry:流程的入口,告诉webpack从哪一个文件开始打包,方式包括:字符串、对象、函数等。

字符串写法

const config = {
  entry: './entry/file.js'
};

module.exports = config;
复制代码

对象写法

const config = {
  entry: {
    app: './src/app.js',
    vendors: './src/vendors.js' //第三方库入口
  }
};
复制代码

多页面

const config = {
  entry: {
    pageOne: './src/pageOne/index.js',
    pageTwo: './src/pageTwo/index.js',
    pageThree: './src/pageThree/index.js'
  }
};
复制代码

至于函数的方式,能够有逻辑处理的发挥空间,最终返回的仍是字符串或者对象。

chunk:字面意思是代码块,存在依赖关系的模块在打包时被封装为一个chunk bundle:由chunk获得的打包产物

因此三者的关系如图:

先消除一个可能的误解,并不是是一个entry项对应一个chunk,对应一个bundle,均可能是多个,后面会再说。

output:设置输出路径和文件

单入口

const config = {
  output: {
    filename: 'bundle.js',
    path: '/public/assets'
  }
};

module.exports = config;
复制代码

多入口

{
  entry: {
    app: './src/app.js',
    about: './src/about.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  }
}
复制代码

这里就遇到了上面提到的”多对多“的关系。

其中filename是输出资源文件名,不只能够是名称,还能够是相对路径,并且目录不存在也不要紧,会自动建立。

能够看到,filename 使用了[name],这是由于多个文件须要生成多个对应的文件,[name]相似模板语言,意图是根据入口文件动态生成文件名,以确保惟一性。

固然,[name]只是模板变量之一,还有能够控制客户端缓存的[hash][chunkhash]等,能够精确地让相应文件在客户端获得更新。就像这样

output:{
  filename:'[name]@[hash].js'
}
复制代码

loader:字面意思是装载器,能够理解为”预处理器“,Webpack自己只认识JavaScript,对其余类型,好比:样式、图片等,必须预约义一个或多个loader对其进行转译,因此loader赋予webpack处理不一样资源的能力,丰富了扩展性。

用法示例以下:

首先说明,loader不是webpack自带的,须要安装,好比咱们处理样式。

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

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

能够看出,loader的套路很简单:

  1. 文件类型
  2. 对应loader

须要说明的是:

  1. css-loader 自己仅处理样式的加载,并不负责将样式插入页面,因此一般配合 style-loader 一块儿使用,预处理器一样。
  2. use数组当中的loader顺序是有讲究的,它是从后往前进行处理,搞错了顺序一样没法达到想要的效果。

plugin: loader是作某些类型文件的模块转换工做,相比之下,plugin是用来完成一些loader职责以外的任务,更多,更丰富,也加强了webpack的能力。

用法以下:

plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
]
复制代码

它的可配置项有不少,这里再也不列举,只要知道它是一个具备 apply 属性的 JavaScript ,能够携带参数,因此要向plugin属性传入 new 实例。

配置文件

说到这儿,你可能以为都是零散的概念,它们应该放在哪儿?

有一种”最佳实践“叫配置分离,即配置文件单独放在一个文件当中,node有package.json,webpack也有,咱们上面提到的全部,都应该写在一个叫webpack.config.js的文件当中。譬如:

//webpack.config.js
var path = require('path');

module.exports = {
  mode: 'development',  //模式,分为 development 和 production
  entry: './index.js',
  output: {
    path: path.resolve(__dirname, 'dist'),
    filename: 'index.bundle.js'
  },
  module: {
    rules: [
      {
        test: /\.css$/,
        use: ['style-loader','css-loader']     
      }
    ]
  },
  plugins: [
    new HtmlWebpackPlugin({template: './src/index.html'})
  ]
};
复制代码

最基本的配置就是这样了,若是看作是一条生产线的话,就是从入口文件进,从dist输出。

实际开发中会加入更多逻辑和工具,代码量会大大增长,但使用方法相似。

更多配置

经常使用loader

说到这儿,你可能会问,我知道webpack拿loader做为工具,但有哪些工具可用呢?下面介绍几个:

  • babel-loader

用途你们都很熟,把ES6+代码编译为ES5,可让你们在浏览器支持度不是很充分的状况下用新方法编码。

推荐安装:babel-loader @babel/core @babel/preset-env

  • ts-loader

用于链接Webpack和Typescript。

  • html-loader

前面说过,Webpack只认识js,这个loader用于将HTML文件转化为字符串并格式化,经过js加载。

  • file-loader

打包文件类型资源,返回publicPath。 对publicPath稍做解释,前面咱们看到过path,它是资源打包路径,而publicPath是资源引用路径,即页面当中作引用的静态文件(图片等)。

  • vue-loader

这个应该不少人在用,处理vue组件,除此以外,可能还要安装vue-template-compiler以及前面提到的样式处理loader等。

更多loader

经常使用插件

  • html-webpack-plugin

自动生成html文件,而且引用相关的 assets 文件。

  • mini-css-extract-plugin

分离CSS,将CSS提取到单独的文件中,支持CSS和sourceMap的按需加载。

  • uglifyjs-webpack-plugin

对js进行压缩混淆。

  • Hot Module Replacement

浏览器自动更新,实时预览修改效果

  • CommonsChunkPlugin/SplitChunks

把多个chunk中的公共部分提取出来,减小重复打包,缩小资源说起,能够更有效利用客户端缓存。

更多插件

总结

文章已经有点长,但仍有不少东西没有讲到,没有深刻,旨在跟你们分享webpack的用途以及大体用法,更详细内容及工具可移步官网查看。

但对于创建初步的认识应该足够,剩下的,各公司或者业务的特色都不同,你们可根据具体状况进行定制,总之,工具是为我所用的,是为开发者提供便利的,而不是拦路虎,应该学会并掌握它。

下篇见!~

Webpack上手指北

相关文章
相关标签/搜索