webpack 从入门到放弃

更新日期: 2019-08-03阅读: 2.2k标签: webpack

随着前端项目复杂程度越来越高,依赖也越来越多,为了提高项目中代码的可复用性,前端开始提出模块化开发的思路,前端模块化会有以下几个痛点:

命名冲突
文件依赖
代码复用

模块化,会将相关的代码封装成一个package包的文件,当需要的时候,直接拿来用即可(import引入)。至于相关文件的直接依赖如何处理,webpack会帮我们解决这个问题。那么模块化应该使用什么样的规范呢?常见的模块化的标准主要如下:

commonJs

nodejs使用的就是commonJs的规范,采用的同步方式加载依赖,一个文件就是一个模块。

导入导出方式如下:

导入:const aa = require('./aa')
导出:module.exports = aa.fun

缺点是加载的模块是同步的,只有加载完才能执行后面的操作。因为 node.js 的模块文件一般存在于本地硬盘,所以一般不会出现这个问题,但是在浏览器环境该规范就不那么适用了。

AMD

因为commonJS不适用于浏览器的环境,所以出现AMD规范。特点: 异步加载/推崇依赖前置、提前执行 。require.js最佳实践

使用方式:

定义模块: define()
加载模块:require()
引用:require.config()
CMD

CMD的使用方式如上,但是特点不太一样。CMD是异步加载/依赖就近、延迟执行 sea.js最佳实践

ES6

ES6 直接在语言层面上实现了模块化。我们现在用的最多的就是 ES6 模块化的实践方式。

导入导出方式如下:

导入:
import aa from 'aa'
import {A} from 'aa'

导出:
export default {A, B}
export {A, B}
export funtion aa() {}

虽然ES6是模块化的最终方案,但是还是在许多浏览器上有兼容问题,需要对代码进行转码处理才行。

样式文件中的模块化

前端开发中,样式文件也开始支持模块化,以stylus为例,通常将一些通用的文件放到文件中,在使用相关的样式时,直接@import引入文件,就能使用对应的代码片段,当然也能定义一些全局的参数(颜色,圆角类)进行使用。

// common.styl
.center-transform
  top 50%
  left 50%
  transform translate(-50% -50%)
center-transform()
  top 50%
  left 50%
  transform translate(-50% -50%)

// 使用
@import 'common.styl'
.box {
  center-transform
}


webpack和Gulp/Grunt、Rollup比较

Grunt: 是一套前端自动化工具,帮助处理反复重复的任务。一般用于:编译,压缩,合并文件,简单语法检查等
Gulp: 是基于“流”的自动化构建工具,采用代码优于配置的策略,更易于学习和使用
Rollup: Rollup 是一个和 Webpack 很类似但专注于 ES6 的模块打包工具。 Rollup 的亮点在于能针对 ES6 源码进行 Tree Shaking 以去除那些已被定义但没被使用的代码,以及 Scope Hoisting 以减小输出文件大小提升运行性能。 但是Rollup 生态链还不完善,体验不如 Webpack。
webpack: Webpack 是模块化管理工具和打包工具。通过 loader 的转换,任何形式的资源都可以视作模块,比如 CommonJs 模块、AMD 模块、ES6 模块、css、图片等。它可以将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还可以将按需加载的模块进行代码分隔,等到实际需要的时候再异步加载


开始使用webpack

首先创建一下的目录结构:

.
├── src
│   ├── assemble
│   │   ├── css
│   │   │   ├── index.css
│   │   ├── index.html
│   │   └── js
│   │       ├── index.js
│   │       └── test.js
│   ├── babyTest
│   │   ├── css
│   │   │   └── index.css
│   │   ├── index.html
│   │   └── js
│   │       └── index.js


文件内容:
// 1. assemble-index.html: 
<html lang="zh-CN">
<head>
  <meta charset="UTF-8">
  <title></title>
</head>
<body>
</body>
</html>

// 2. assemble-css/index.css:
body {background: red} 

// 3. assemble-js/index.js:
import '../css/index.css'
console.log('index.js')


// 4. assemble-js/test.js:
console.log('test.js')

babyTest目录和上面类似
创建package.json文件: npm init
安装webpack(全局、目录安装):npm install webpack -D

创建webpack.config.js文件,下面直接配置的是多文件入口:

// 引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin')
// 相关配置
module.exports = {
 mode: 'development', // 指定webpack的模式  
 entry: {
   'assemble/js/index': './src/assemble/js/index.js',
   'assemble/js/test': './src/assemble/js/test.js',
   'babyTest/js/index': './src/babyTest/js/index.js'
 },
 output: {
   filename: '[name].js',  // 打包后输出文件的文件名
   path: path.resolve('./output/market') // 打包后的文件存放的地方
 },
 module: {
   rules: [
     {
       test: /\.css$/,
       use: ['style-loader', 'css-loader']
     }
   ]
 },
 plugins: [
   new HtmlWebpackPlugin({
     template: './src/assemble/index.html',
     filename: 'assemble/index.html',
     chunks: ['assemble/js/index']
   }),
   new HtmlWebpackPlugin({
     template: './src/babyTest/index.html',
     filename: 'babyTest/index.html',
     hash: true,
     chunks: ['babyTest/js/index']
   })
 ]
}

上面写的实例中,将loader和plugins已经使用了,可以先按照上面的使用,后边将进行详细方法的介绍。

使用前,安装对应的依赖包

npm install css-loader style-loader html-webpack-plugin -D
终端执行打包命令: webpack

可以看到在根目录下有output目录,里面就行对应的打包文件。直接运行output文件下的目录,能够看到对应效果,css和js都能够执行成功。

备注:执行打包命令的方式有以下几种方式

node_modules/.bin/webpack
webpack在package.json文件中配置对应的命令 "scripts": { "start": "webpack"}

entry

入口起点(entry point)指示 webpack 应该使用哪个模块,来作为构建其内部依赖图的开始。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖的。

每个依赖项随即被处理,最后输出到称之为 bundles 的文件中,,entry属性 来指定一个入口起点(或多个入口起点)。默认值为 ./src。

output

output 属性告诉 webpack 在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist。基本上,整个应用程序结构,都会被编译到你指定的输出路径的文件夹中。  

Loader

loader 用于对模块的源代码进行转换。loader 可以使你在 import 或"加载"模块时预处理文件。因此,loader 类似于其他构建工具中“任务(task)”,并提供了处理前端构建步骤的强大方法。loader 可以将文件从不同的语言(如 TypeScript)转换为 JavaScript,或将内联图像转换为 data URL。loader 甚至允许你直接在 JavaScript 模块中 import CSS文件!

上面的配置中就用到了 css-loader和style-loader,主要是在对引用的css文件会用style-loader和css-loader进行处理,当配置多个loader的时候,按照从左至右的方式进行处理。

Loaders的配置主要包含以下配置:

test(必填): 用正则匹配对应文件的扩展名
use(必填):loader的名称
include/exclude(非必填):手动添加必须处理或者是忽略的文件
query(非必填):为loaders提供额外的设置选项

在webpack中使用的方式

命令行调用:webpack --module-bind jade --module-bind 'css=style!css'
通过require:require('style-loader!css-loader?minimize!./main.css')
使用配置文件: 如上配置

联系紧密的babel

Babel是一个编译JavaScript的平台,可以帮我们将编译的代码

让你能使用最新的JavaScript代码(ES6,ES7...),而不用管新标准是否被当前使用的浏览器完全支持
让你能使用基于JavaScript进行了拓展的语言

Babel的安装与使用

Babel的安装

Babel其实是几个模块化的包,其核心功能称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用的最多的就是解析ES6语法的包 babel-preset-env)
npm install --save-dev babel-core babel-loader babel-preset-env

在webpack.config.js中,module的rules中添加;

{
  test: /\.js$/,
  use: {
    loader: 'babel-loader',
    options: {
      presets: [
        'env', 'react'
      ]
    }
  },
  include: /src/,
  exclude: /node_modules/
}
Babel的配置

Babel的配置可以直接在webpack.config.js中进行配置,但是有时配置项过多,但在这个文件中配置过多js编译规则的代码,显得可读性不太好,因此支持在.babelrc中单独配置,webpack会自动调用这个文件中的配置项。

// .babelrc文件
{
  "presets": ["react", "env"]
}

loader的特性(引用官网)

loader 支持链式传递。能够对资源使用流水线(pipeline)。一组链式的 loader 将按照相反的顺序执行。loader 链中的第一个 loader 返回值给下一个 loader。在最后一个 loader,返回 webpack 所预期的 JavaScript。
loader 可以是同步的,也可以是异步的。
loader 运行在 Node.js 中,并且能够执行任何可能的操作。
loader 接收查询参数。用于对 loader 传递配置。
loader 也能够使用 options 对象进行配置。
除了使用 package.json 常见的 main 属性,还可以将普通的 npm 模块导出为 loader,做法是在 package.json 里定义一个 loader 字段。
插件(plugin)可以为 loader 带来更多特性。
loader 能够产生额外的任意文件。


扩展-常使用的loader清单

loader name介绍
css-loader解析@import 和 Url()引用的css文件,转化成 import/require() 的方式然后在解析他们
style-loader将 CSS 放在 <style></style> 标签中注入到 dom
sass-loader将 SASS/SCSS 转换为 css
less-loader将 less 转化为 css
html-loader将 html 输出为字符串,也可以根据配置进行压缩
babel-loader加载 ES2015+ 代码,然后使用 Babel 转译为 ES5
url-loader将文件加载为 Base64 编码的 URL
file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置



plugin

插件是 webpack 的支柱功能。webpack 自身也是构建于,你在 webpack 配置中用到的相同的插件系统之上!

插件目的在于解决 loader 无法实现的其他事。

Plugins在构建的过程中,通过在构建流程中注入对应的钩子,给webpack带来很大的灵活性。

Loaders和Plugins常常被弄混,但是他们其实是完全不同的东西,可以这么来说,loaders是在打包构建过程中用来处理源文件的(JSX,Scss,Less..),一次处理一个,Plugins并不直接操作单个文件,它直接对整个构建过程其作用

上面的实例中就使用了html-webpack-plugin插件,主要的功能就是自动引用使用的js文件,使用css的话,也会根据一定规则进行动态插入,在控制台查看文件代码时,可以看到引用的css文件,会自动插在<head></head>之间。如截图所示

我们可以根据自己的项目构建方式,使用对应的插件,就不一一举例说明了。

扩展-常用的Plugins清单

Plugins name介绍
HtmlWebpackPlugin简单创建 HTML 文件,用于服务器访问
clean-webpack-plugin删除指定的文件夹
webpack-bundle-analyzerwebpack打包体积查看,便于优化文件体积
speed-measure-webpack-plugin查看测量出在你的构建过程中,每一个 Loader 和 Plugin 的执行时长(优化webpack时能帮你看出对应的时间)



启动静态服务器

启动一个静态服务器,默认会自动刷新,就是说你对html,css,js文件做了修改并保存后,浏览器会默认刷新一次展现修改后的效果

正常情况下我们都是在开发环境中开发项目,所以之前配置的脚本"dev"可以派上用场了,在执行npm run dev命令后,会启动静态服务器,我们访问localhost:3000端口就可以看到开发的页面内容了

对应的配置文件:

// webpack.config.js的配置文件
devServer: {
  host: 'localhost',  // 默认是localhost
  port: '3000',   // 端口
  open: true,    // 自动打开
  hot: true,    // 开启热更新
  openPage: 'assemble'  // 默认打开的文件
}

// package.json中的配置
"scripts": {
  "dev": "webpack-dev-server --open"
}


开发、测试、上线构建的细微区别

通常本地开发,测试和线上的构建方式略微有点区别,线上文件都会将文件中的空行,空格,换行清除,并且压缩html,css,js和对应image的体积,这样就能保证体积最小,加快页面的加载速度。

但是开发和测试环境通常,在浏览器中,无法对代码逐行打断点进行调试,所有需要使用source maps进行调试,它使得我们在浏览器中可以看到源代码,进而逐行打断点调试。

使用source maps方法

在webpack.config.js文件中,添加devtool属性,赋值为 source-map或者inline-source-map即可,后者报错信息更加具体,会指示源代码中的具体错误位置,而source-map选项无法指示到源代码中的具体位置。


webpack优化

1. 代码编写过程中遇到的现象

问题描述:更改一个文件,导致所有的文件都会重新进行编译。

修改前:

修改后:

优化方案:使用缓存

安装cache-loader模块 npm install cache-loader -D
在module.rules对应的loader最前面添加cache-loader


链接: https://www.fly63.com/article/detial/5089

浅谈Webpack打包工具的应用

webpack 在前端工程中随处可见,当前流行的 vue, react, weex 等解决方案都推崇 webpack 作为打包工具。前端工具云集的时代,这是你值得选择的之一。

一步一步webpack,webpack的学习入门

webpack是前端工程构建的一套工具,为什么一个程序称之为一套呢,是因为webpack其实是npm的一个模块,使用起来的话,这期间还需要很多其它模块来进行支持,所以我称之为一套工具。

如何写 Webpack 配置文件

本文从一个小Demo开始,通过不断增加功能来说明webpack的基本配置,只针对新手。webpack基本的配置就可以熟悉了,会引入loader,配置loader选项,会设置alias,会用plugins差不多。

WebPack中Plugins的使用和整理,以及常用的Plugins插件

Plugins是webpack的基础,我们都知道webpage的plugin是基于事件机制工作的,这样最大的好处是易于扩展。讲解如果扩展内置插件和其他插件,以及我们常用的Plugins插件

大多数项目中会用到的webpack小技巧

webpack技巧的总结:进度汇报、压缩、复数文件打包、分离app文件与第三方库文件、资源映射、输出css文件、开发模式、分析包的大小、更小的react项目、更小的Lodash、引入文件夹中所有文件、清除extract-text-webpack-plugin日志。

优化Webpack构建性能的几点建议

Webpack 作为目前最流行的前端构建工具之一,在 vue/react 等 Framework 的生态圈中都占据重要地位。在开发现代 Web 应用的过程中,Webpack 和我们的开发过程和发布过程都息息相关,如何改善 Webpack 构建打包的性能也关系到我们开发和发布部署的效率。

Webpack 4正式发布了!

新版 Webpack 中我们所做的每一个更新目的都在于此,为了当大家在使用 Webpack 的时候敏捷连续毫无顿挫感。 webpack 4 进行构建性能测试,得出的结果非常有趣。结果很惊人,构建时间降低了 60%-98%!

Webpack 4.0.0不再支持 Node.js 4

Webpack 是一个现代 JavaScript 应用程序的模块打包器 (module bundler) 。当 Webpack 处理应用程序时,它会递归地构建一个依赖关系图,其中包含应用程序需要的每个模块

我当初为什么写webpack_Tobias Koppers

Tobias Koppers是一位自由软件开发者,家住德国纽伦堡。他因写出webpack这个已有数百万开发者使用的开源软件而名噪一时。他目前专注于JavaScript和开源项目。以下是我对他个人的专访,希望对大家有所启发。

webpack项目轻松混用css module

本文讲述css-loader开启css模块功能之后,如何与引用的npm包中样式文件不产生冲突。比如antd-mobilenpm包的引入。在不做特殊处理的前提下,样式文件将会被转译成css module。

点击更多...

内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!