webpack学习文档

一、webpack是什么
webpack是前端资源模块化管理和打包工具。它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Sass,TypeScript等),并将其打包为合适的格式以供浏览器使用。

二、为什么要使用webpack
在很久以前,纯 HTML + CSS + JavaScript 开发,不需要打包工具,直接把写好的HTML 用浏览器打开就能显示出一个网页。
随着时代的发展,前端出现了很多新技术:
1.前端人不再用 css,而是用 Less、Sass、Stylus 这样的预处理语言;
2.前端不再通过JS或者JQ修改DOM,而是使用各种框架,比如Vue,React;
3.前端人开始尝试语言的新特性,比如 ES6、ES7,现在流行起来使用TypeScript,可是这些新特性并不适用于所有浏览器;
4.为了让代码体积更小,前端人开始对 CSS、JavaScript、HTML、图片等进行压缩处理;
5.项目越来越大,前端人开始追求模块化开发;
从代码的角度来说,webpack 能够把一种代码转换成另一种浏览器能够识别的代码。


image.png

三、核心概念


image.png

1.入口(entry)
webpack将创建所有应用程序依赖关系图表。入口起点告诉webpack从哪里开始,并遵循着依赖关系图表知道打包什么。进入入口起点后,webpack 会找出有哪些模块和库是入口起点(直接和间接)依赖。
2.出口(output)
将所有资源打包在一起后,告诉webpack将打包资源输出到什么地方,以及如何命名这些文件。
3.加载器(loader)
webpack 只能理解 JavaScript 和 JSON 文件,loader 用于转换webpack不能读取的文件类型。它相当于一个语言的翻译官,比如可以把 less 翻译成 css,把 TypeScript 翻译成 js。
4.插件(plugins)
webpack的插件系统极其强大和可定制,用于执行范围更广的任务。plugin可以监听 webpack 在打包过程中发出的事件,比如 webpack 处理 index.js 这个文件时,会发出事件,plugin 可以接收到这个事件,对 index.js 这个文件进行处理。
5.模式(mode)
打包模式,支持 development(开发模式,方便调试) 和 production(生产模式,会做各种优化处理,比如文件压缩)。

webpack的简单配置如下(webpack.config.js):

// path 为 node 提供的模块,可直接使用
const path = require('path');
// 通过 npm 安装,主要作用自动生成主页index.html
const HtmlWebpackPlugin = require('html-webpack-plugin');

module.exports = {
  // 设置打包方式,支持 development 和 production
  mode: 'development',
  // 打包入口文件
  entry: './src/index.js',
  // 最终打包输出配置
  output: {
    filename: 'bundle.js',
    path: path.resolve(__dirname, './dist')
  },
  // 配置 loader,不同文件应用不同的 loader
  module: {
    rules: [
        {
          // vue 文件采用 vue-loader 来处理
          test: /\.vue$/,
          use: ['vue-loader']
        },
        {
          // css 文件,先采用 css-loader 处理,
          // 再使用 style-loader 处理,注意顺序
          test: /\.css$/,
          //css-loader允许在js中import一个css文件,会将css文件当成一个模块引入到js文件中
          //style-loader能够在需要载入的html中创建一个<style></style>标签,标签里的内容就是CSS内容
          use: ['style-loader', 'css-loader']
        }
    ]
  },
  //配置插件,为了使用插件,需要require它们,并且添加到plugins数组
  plugins: [
    //使用new来创建插件的实例
    new HtmlWebpackPlugin({
      // <%= htmlWebpackPlugin.options.title %>模板语法,模板可使用
      title: '自定义',
      filename: 'custom.html',
      // 指定模板文件
      template: 'public/index.html'
    })
  ]
}

四、模块热替换(HMR)

模块热替换(HMR - hot module replacement)功能会在应用程序运行过程中,替换、添加或删除模块,而无需重新加载整个页面。主要是通过以下几种方式,来显著加快开发速度:

  • 保留在完全重新加载页面期间丢失的应用程序状态。
  • 只更新变更内容,以节省宝贵的开发时间。
  • 在源代码中 CSS/JS 产生修改时,会立刻在浏览器中进行更新,这几乎相当于在浏览器 devtools 直接更改样式。

HMR是 webpack 提供的最有用的功能之一,此功能可以很大程度提高开发效率。我们要做的就是更新 webpack-dev-server 配置, 然后使用 webpack 内置的 HMR 插件。

module.exports = {
    //...
    devServer: {
      //如果编译报错,会抛出错误,你重新改成正确的,这个时候又会触发重新编译,整个浏览器会重新刷新!
        hot: true, 
    }
}

五、如何写一个webpack插件

一个 js 命名函数。
在原型链上存在一个 apply 方法。
为该插件指定一个 Webpack 的事件钩子函数。
使用 Webpack 内部的实例对象(Compiler 或者 Compilation)具有的属性或者方法。
如果是异步插件,当功能完成以后,需要执行 Webpack 的回调函数。

Compiler 对象: 该对象在 Webpack 启动的时候会被创建,同时该对象也会被传入一些可控的配置,如 Options、Loaders、Plugins。
Compilation 对象:该对象表示本次打包的模块、编译的资源、文件改变和监听的依赖文件的状态。

下面我们写一个自定义插件commentPlugin.js,在打包时去除文件中的注释。

class CommentPlugin {
  //Webpack 要求插件必须是一个函数或者是一个包含 apply 方法的类
  //apply()会在 Webpack 启动时被调用,接收 compiler 对象参数,这个对象是 Webpack 工作过程中最核心的对象,包含了此次构建的所有配置信息
  apply (compiler) {
    //通过 compiler 对象的 hooks 属性访问到 emit 钩子,再通过 tap 方法注册一个钩子函数
    compiler.hooks.emit.tap('CommentPlugin', compilation => {
      // compilation => 可以理解为此次打包的上下文
      // compilation对象中的 assets 属性获取即将写入输出目录的资源文件信息
      for (const name in compilation.assets) {
        if (name.endsWith('.js')) {
          //文件内容需要通过遍历的值对象中的 source 方法获取
          const contents = compilation.assets[name].source()
          const noComments = contents.replace(/\/\*{2,}\/\s?/g, '')
          compilation.assets[name] = {
            source: () => noComments,
            size: () => noComments.length
          }
        }
      }
    })
  }
}
module.exports=CommentPlugin;

在webpack.config.js文件中配置CommentsPlugin插件:

const CommentsPlugin = require("./comments-plugin.js");
module.exports = {
  //...其他配置信息
  plugins: [
    //使用时通过new操作符创建一个实例对象去使用这个插件
    new CommentsPlugin(),
  ],
};

六、常用插件
https://blog.csdn.net/weixin_43720095/article/details/107720200

七、总结
webpack在打包的时候,需要通过 webpack.config.js 这个文件告诉它,打包先从哪个文件开始,比如先从 index.js 文件开始,index.js 文件又引用了 a.js 和 b.js 文件,那么 webpack 在处理的时候会把这些文件合并到一个文件中。最终需要一个 output(出口)告诉 webpack 把最终生成的文件要放到哪个地方。不同的文件要通过相应的loader来处理成webpack能理解的模块,插件主要用来扩展 webpack 的功能。总的来说,webpack 就是一个前端打包工具,它拥有非常多的小工具,可以把代码从开发模式变成线上模式,最终交给浏览器渲染。

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

推荐阅读更多精彩内容