webpack打包学习笔记之理论篇(一)

什么是webpack

官方概念

webpack 是现代 js 应用程序的静态模块打包器,当 webpack 处理应用程序时,它会递归的构建一个依赖关系图,其中包含应用程序需要的每个模块,然后将所有这些模块打包成一个或多个bundle。

个人理解

webpack可以看做是模块打包机,主要做的事情是,分析项目结构,找到 js 模块以及其他的一些浏览器不能直接运行的扩展语言(scss ts等)将其转换和打包为合适的格式供浏览器使用

模块和打包的由来

模块

曾经的前端开发方式,js文件是通过 script 标签静态引入,js 文件之间没有强依赖关系,如果文件 1 要用到文件 2 的某些方法或变量,必须将文件 1 放在文件 2 的后面加载,随着项目的增大, js 文件之间的依赖关系越来越复杂,维度难度也越来越高,从而引入模块的概念让 js 文件之间可以相互引用,例如模块 1 要使用模块 2 的功能,只需要在该模块 1 中明确引用模块 2 就可以,不用担心它们的引用顺序,因此基于这种理念, 有了 Commonjs、AMD 规范被创造出来,有了 require.js system.js 这样的前端模块加载工具和 node 模块系统以及现在流行的 es6 module

打包

模块的引入是为了解决文件之间依赖引用的问题,打包是为了解决文件过多问题,当项目规模增大,模块的数量数以千计,浏览器加载如此多的文件,页面的加载速度会受到影响,而 bundle 可以把多个关联的文件打包到一起从而减少文件的数量提高网页加载性能

模块化打包工具的由来

1、解决开发阶段代码在实际生产运行环境中兼容性问题

image

2、将零散的模块文件打包到统一的文件中,避免由于模块文件过多造成频繁的网络请求

image

3、实现所有前端资源的模块化,不仅仅是 js 模块化

image

webpack和grunt gulp的区别

grunt 和 gulp 的工作方式是:在一个配置文件中,指明对某些文件进行类似编译、组合、压缩等任务的具体步骤,使用工具之后可自动替你完成这些任务

webpack工作方式是:把项目当做一个整体,通过给定的主文件,将从这个主文件找到项目的所有依赖文件,使用 loaders处理,最后打包为一个或多个浏览器可以识别的 Js 文件

核心概念

模块(module)

对于 webpack ,模块不仅仅是 js 模块,它包括了任何类型的源文件,不管是图片、字体、json文件都是一个个模块,webpack支持以下方式引用模块:

1、es5 import 方法

2、CommonJs require()方法

3、AMD define和 require语法

4、css/sass/less文件中的 @import 语法

5、url(...) 和 <img src=...>中的图片路径

依赖关系图

是 webpack 根据每个模块之间的依赖关系生成的一张内部逻辑图,根据这张依赖图,webpack能按图把所需要的模块打包成一个 bundle 文件

入口(entry)

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

1、单入口

const config = {
   entry: 'index.js'
}

2、多入口

const config = {
  pageOne: 'index1.js',
  pageTwo: 'index2.js'
}

出口(output)

output属性告诉 webpack在哪里输出它所创建的 bundles,以及如何命名这些文件,默认值为 ./dist 基本上,整个应用程序结构,都会被编译到你指定的输出路径文件夹中。
用法:
在 webpack 中配置 output属性的最低要求是,将它的值设置为一个对象,包括以下两点
filename: 输出文件的文件名
path: 目标输出目录(为绝对路径)
单个入口起点

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

** 多个入口起点 **

const config = {
  entry: {
    app: './src/app.js',
    search: './src/search.js'
  },
  output: {
    filename: '[name].js',
    path: __dirname + '/dist'
  },
}

补充说明 webpack打包中 path.resolve和__dirname的含义
1、path 是 node中的一个核心模块。path.resolve将路径或路径的片段解析为绝对路径,原则是给定的路径序列会从右到左处理,后面的每个 path 会被追加到前面,直到构造出绝对路径
总结
参数从右向前,若字符以/ 开头,返回值不会拼接到前面的路径;若以 ../ 开头,返回值拼接前面的路径,但是不包含前面路径的最后一层路径;若以 ./开头或者没有符号,则拼接前面的路径
举例如下:

当前的工作路径为/workspace/demo
console.log(path.resolve())           // returns /workspace/demo
console.log(path.resolve(''))         // returns /workspace/demo
console.log(path.resolve(__dirname))  // returns /workspace/demo
console.log(path.resolve('/img/books', '/net'))   // returns '/net'
console.log(path.resolve('img/books', '/net'))    // returns '/net'
console.log(path.resolve('img/books', './net'))   // returns '/workspace/demo/img/books/net'
console.log(path.resolve('/img/books', './net'))   // returns '/img/books/net'
console.log(path.resolve('/img/books', 'net'))     // returns '/img/books/net'
console.log(path.resolve('/img/books', '../net'))         // returns '/img/net'
console.log(path.resolve('src','/img/books', '../net'))   // returns '/img/net'
console.log(path.resolve('src','./img/books', '../net'))   // returns '/workspace/demo/src/img/net'
console.log(path.resolve('src','img/books', '../net'))     // returns '/workspace/demo/src/img/net'

2、__dirname获得当前文件所在目录的完整路径名

模式

通过选择 development 或 production 之中的一个,来设置 mode 参数,可以启用相应模式下的 webpack 内置的优化
1、production: 生产模式,会启用内置的插件对打包的代码进行压缩优化等操作
2、development: 开发模式,更注重打包效率,不对代码进行压缩
3、none: 纯打包模式,以原始的状态打包代码

module.exports = {
  mode: 'production'
}

loader

loader 让 webpack 能够处理那些非 js 文件(webpack 自身只理解 Js)。loader可以将所有类型的文件转换为 webpack 能够处理的有效模块,然后就可以利用 webpack的打包能力,对它们进行处理

使用方式
1、test 属性:用于标识出应该被对应的 loader 进行转换某个或某些文件
2、use属性:表示进行转换时,应该使用哪个 loader

const path =  require('path');
const config = {
  module: {
     rules: [
       {
        test: /\.txt$/, use: 'raw-loader'
      }
    ]
  }
}
实现过程:此段代码告诉 webpack 解析器,当遇到 repuire import语句中被解析为 .txt的路径时,对它打包之前,先使用 raw-loader转换一下

插件(plugins)

plugin 主要是用来扩展 webpack 功能的,通过在构建流程里注入钩子实现,给 webpack带来了很大的灵活性
使用方法
1、在 webpack 的配置中,向 plugins 属性传入 new 实例
基本使用方式

(1)引入插件
const HtmlWebpackPlugin = require('html-webpack-plugin');
(2)配置插件
 plugins: [
     new HtmlWebpackPlugin()
  ]

配置

webpack 的配置文件,是导出一个对象的 js 文件,此对象,由 webpack 根据对象定义的属性进行解析;
webpack 配置是标准的 Node.js CommonJS 模块,可以做到以下事情:
1)通过 require(...) 导入其他文件
2)通过 require(...) 使用 npm 的工具函数
3)使用 js 的控制流表达式,例如 ?:
4)对常用值使用常量或变量
5)编写并执行函数来生成部分配置

基本配置
 const path = require('path');
module.exports = {
  mode: 'development',
  entry: './foo.js',
  output: {
     path: path.resolve(__dirname,'dist'),
     filename: 'foo.bundle.js'
  }
 }

模块

模块
开发者将程序分解成离散功能模块,称之为模块;
模块特点
每个模块具有比完整程序更小的接触面,使得校验、调试、测试轻而易举。精心编写的模块提供了可靠的抽象和封装界限,使得应用程序中每个模块都具有条理清楚的设计和明确的目的
什么是webpack模块

  1. es5 的 import 语句
    2)CommonJs 的 require 语句
    3)AMD 的 define 和 require 语句
  2. css/sass/less 文件中的 @import 语句
    5)样式 url(...)或HTML文件<img src=‘...’>中的图片链接

模块解析

resolver 是一个库,用于帮助找到模块的绝对路径,一个模块可以作为另一个模块的依赖模块,被引用
webpack解析规则
主要解析三种文件路径
1)绝对路径

import "/home/me/file"
  1. 相对路径
import "../src/file"
  1. 模块路径
import "module"

模块将在 resolve.modules中指定的所有目录内搜索,可以替换初始模块路径,替换初始路径可以通过 resolve.alias 创建一个别名

module.exports = {
 resolve: {
    alias: {
       'vue': 'vue/dist/vue.js'
     }
  }
 }

manifest

Runtime
runtime 以及伴随的 manifest 数据,主要是指:在浏览器运行时,webpack用来连接模块化的应用程序的所有代码
Manifest
当编译器开始执行、解析和映射应用程序时,会保留所有模块的详细要点。

构建目标(targets)

因为服务器和浏览器代码都可以用 js 编写,所以 webpack 提供了多种构建目标,配置如下:

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

推荐阅读更多精彩内容