webpack(个人笔记)

webpack官网:https://webpack.js.org/
webpack中文文档: https://www.webpackjs.com/concepts/

image.png

1.什么是webpack

概念:本质上,webpack 是一个现代 JavaScript 应用程序的静态模块打包器(module bundler)。当 webpack 处理应用程序时,它会递归地构建一个依赖关系图(dependency graph),其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个 bundle

简单理解:webpack是一个打包模块化javascript的工具,在webpack里一切文件皆模块,通过loader转换文件,通过plugin注入钩子,最后输出由多个模块组合成的文件,webpack专注构建模块化项目。
WebPack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。

2.基本使用

webpack基本使用

基本使用.png
配置入口与出口.png

自动打包.png

生成直接预览页面.png

配置完访问localhost:8080可以直接访问页面(不配置的话访问看到的页面是项目目录,然后再点击进去访问)


打包完自动打开页面.png

配置完运行npm run dev打包之后可以直接打开页面,不用再复制访问地址。

webapck的加载器loader

loader加载器1.png

没有loader加载器打包css文件报错:

没有loader加载器报错.png

基本使用:

loader加载器基本使用1.png
less-loader.png
sass-loader.png
处理css兼容问题.png
url-loader.png

webpack默认不打包样式表中的图片,如css文件中的背景图片的url。所以需要借助url-loader来进行打包,否则会报错。

打包js高级语法.png

几个常见的loader

  • file-loader:把文件输出到一个文件夹中,在代码中通过相对 URL 去引用输出的文件

  • url-loader:和 file-loader 类似,但是能在文件很小的情况下以 base64 的方式把文件内容注入到代码中去

  • source-map-loader:加载额外的 Source Map 文件,以方便断点调试

  • image-loader:加载并且压缩图片文件

  • babel-loader:把 ES6 转换成 ES5

  • css-loader:加载 CSS,支持模块化、压缩、文件导入等特性

  • style-loader:把 CSS 代码注入到 JavaScript 中,通过 DOM 操作去加载 CSS。

  • eslint-loader:通过 ESLint 检查 JavaScript 代码

webpack中的plugin

什么是plugin

plugin是一个具有 apply方法的 js对象。 apply方法会被 webpack的 compiler(编译器)对象调用,并且 compiler 对象可在整个 compilation(编译)生命周期内访问。

一个plugin看起来大概是这个样子:

 function CustomPlugin(options){
    // options是配置文件,你可以在这里进行一些与options相关的工作
  }
  ​
  // 每个plugin都必须定义一个apply方法,webpack会自动调用这个方法
  CustomPlugin.prototype.apply = function(compiler){
      ......
      });
  }
  ​
  module.exports = CustomPlugin;

plugin有什么用

plugin是webpack核心功能,通过plugin(插件)webpack可以实现loader所不能完成的复杂功能,使用plugin丰富的自定义API,可以控制webpack编译流程的每个环节,实现对webpack的自定义功能扩展。

举例 我们实际项目中就使用了HtmlWebpackPlugin插件,它帮助我们做了下面几件事儿:

  • 在工程打包成功后会自动生成一个html模板文件

  • 同时所依赖的CSS/JS也都会被自动引入到这个html模板文件中

  • 设置生成hash添加在引入文件地址的末尾,类似于我们常用的时间戳,来解决可能会遇到的缓存问题。

使用plugin

在 webpack 配置文件(webpack.config.js)中,向 plugins 属性传入 new 实例即可。比如:

 const HtmlWebpackPlugin = require('html-webpack-plugin');
  const webpack = require('webpack');
  module.exports = {

    module: {
      loaders: [
        {
          test: /\.(js|jsx)$/,
          loader: 'babel-loader'
        }
      ]
    },
    plugins: [
      new webpack.optimize.UglifyJsPlugin(), //访问内置的插件
      new HtmlWebpackPlugin({template: './src/index.html'}) //访问第三方插件
    ]
  };

注意

  • webpack中的插件分为内置插件和第三方插件

  • 内置插件不需要额外安装依赖,如上面的例子中:UglifyJsPlugin插件

  • 如果是第三方插件,如上面的例子中HtmlWebpackPlugin插件,则使用之前需要进行安装:

npm install html-webpack-plugin --save-dev</pre>

几个常见的plugin

  • BannerPlugin:对所有的文件打包后添加一个版权声明

  • uglifyjs-webpack-plugin: 对JS进行压缩混淆

  • HtmlWebpackPlugin:可以根据模板自动生成html代码,并自动引用css和js文件

  • Hot Module Replacement:在每次修改代码保存后,浏览器会自动刷新,实时预览修改后的效果

  • copy-webpack-plugin:通过Webpack来拷贝文件

  • extract-text-webpack-plugin:将js文件和css文件分别单独打包,不混在一个文件中

  • DefinePlugin 编译时配置全局变量,这对开发模式和发布模式的构建允许不同的变量时非常有用

  • optimize-css-assets-webpack-plugin 不同组件中重复的css可以快速去重

  • 更多可点击这里查看。

3.vue-loader

vue-loader.png
webpack中使用vue.png

4.vue中配置webpack

vue中配置webpack.png

5. 关闭eslint

在vue.config.js文件中添加一项lintOnSave: false和在devServer项中设置overlay中的错误提示为false。

 module.exports = {
    devServer: {
      port: 8081,
      open: true,
      overlay: {
        warnings: false,
        errors: false
    }
    },
    lintOnSave: false
  }

6.webpack优缺点

webpack有哪些优点

  • 专注于处理模块化的项目,能做到开箱即用,一步到位

  • 可通过plugin扩展,完整好用又不失灵活

  • 使用场景不局限于web开发

  • 社区庞大活跃,经常引入紧跟时代发展的新特性,能为大多数场景找到已有的开源扩展

  • 良好的开发体验

webpack的缺点

  • webpack的缺点是只能用于采用模块化开发的项目

7.分别介绍bundle,chunk,module是什么

bundle:是由webpack打包出来的文件。 chunk:代码块,一个chunk由多个模块组合而成,用于代码的合并和分割。 module:是开发中的单个模块,在webpack的世界,一切皆模块,一个模块对应一个文件,webpack会从配置的entry中递归开始找出所有依赖的模块。

8.分别介绍什么是loader?什么是plugin

loader:模块转换器,用于将模块的原内容按照需要转成你想要的内容。 plugin:在webpack构建流程中的特定时机注入扩展逻辑,来改变构建结果,是用来自定义webpack打包过程的方式,一个插件是含有apply方法的一个对象,通过这个方法可以参与到整个webpack打包的各个流程(生命周期)。

9.什么是模块热更新

模块热更新是webpack的一个功能,他可以使得代码修改过后不用刷新浏览器就可以更新,是高级版的自动刷新浏览器。 devServer中通过hot属性可以空时模块的热替换

1,通过配置文件

  const webpack = require('webpack');
  const path = require('path');
  let env = process.env.NODE_ENV == "development" ? "development" : "production";
  const config = {
    mode: env,
   devServer: {
       hot:true
   }
  }
    plugins: [
       new webpack.HotModuleReplacementPlugin(), //热加载插件
    ],
  module.exports = config;</pre>

2,通过命令行

  "scripts": {
      "test": "echo \"Error: no test specified\" && exit 1",
      "start": "NODE_ENV=development  webpack-dev-server --config webpack.develop.config.js --hot",
    }

10.什么是Tree-shaking

Tree-shaking可以用来剔除javascript中不用的死代码,它依赖静态的es6模块化语法,例如通过哦import 和export 导入导出,Tree-shaking最先在rollup中出现,webpack在2.0中将其引入,css中使用Tree-shaking需要引入Purify-CSS。

11.通过webpack处理长缓存

浏览器在用户访问页面的时候,为了加快加载速度,会对用户访问的静态资源进行存储,但是每一次代码升级或是更新,都需要浏览器去下载新的代码,最方便和简单的更新方式就是引入新的文件名称。在webpack中可以在output纵输出的文件指定chunkhash,并且分离经常更新的代码和框架代码。通过NameModulesPlugin或是HashedModuleIdsPlugin使再次打包文件名不变。

12.如何提高webpack的构建速度

1. 通过externals配置来提取常用库

2. 利用DllPlugin和DllReferencePlugin预编译资源模块
通过DllPlugin来对那些我们引用但是绝对不会修改的npm包来进行预编译,再通过DllReferencePlugin将预编译的模块加载进来。

3. 使用Happypack 实现多线程加速编译

要注意的第一点是,它对file-loader和url-loader支持不好,所以这两个loader就不需要换成happypack了,其他loader可以类似地换一下

4. 使用Tree-shaking和Scope Hoisting来剔除多余代码

5. 使用fast-sass-loader代替sass-loader

6. babel-loader开启缓存

babel-loader在执行的时候,可能会产生一些运行期间重复的公共文件,造成代码体积大冗余,同时也会减慢编译效率。 可以加上cacheDirectory参数或使用 transform-runtime 插件试试。

// webpack.config.js
  use: [{
      loader: 'babel-loader',
      options: {
          cacheDirectory: true
  }]
  // .bablerc
  {
      "presets": [
          "env",
          "react"
      ],
      "plugins": ["transform-runtime"]
  }

7. 不需要打包编译的插件库换成全局"script"标签引入的方式

比如jQuery插件,react, react-dom等,代码量是很多的,打包起来可能会很耗时 可以直接用标签引入,然后在webpack配置里使用 expose-loader 或 externals 或 ProvidePlugin 提供给模块内部使用相应的变量。

 // @1
  use: [{
      loader: 'expose-loader',
      options: '/pre>
  }, {
      loader: 'expose-loader',
      options: 'jQuery'
  }]
  // @2
  externals: {
      jquery: 'jQuery'
  },
  // @3
  new webpack.ProvidePlugin({
      $: 'jquery',
      jQuery: 'jquery',
      'window.jQuery': 'jquery'
  })

8. 优化构建时的搜索路径

在webpack打包时,会有各种各样的路径要去查询搜索,我们可以加上一些配置,让它搜索地更快 比如说,方便改成绝对路径的模块路径就改一下,以纯模块名来引入的可以加上一些目录路径 还可以善于用下resolve alias别名 这个字段来配置。 还有exclude等的配置,避免多余查找的文件,比如使用babel别忘了剔除不需要遍历的。

参考链接
webpack面试题汇总
Webpack打包构建太慢了?试试几个方法
关于webpack的面试题总结

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,271评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,275评论 2 380
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,151评论 0 336
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,550评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,553评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,559评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,924评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,580评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,826评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,578评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,661评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,363评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,940评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,926评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,156评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,872评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,391评论 2 342