webpack入门学习基础+跑一个简单的实例

https://webpack.docschina.org/api/
https://webpack.docschina.org/
使用webpack构建浏览器和服务器环境的应用(同构应用),即用一份代码分别编译为浏览器和服务器环境下的代码。
所以使用API和模块时需要考量两个环境是否都支持。
在这里插入图片描述
用于模块化开发项目,打包模块化JavaScript
entry入口
module一切文件皆模板
loader转换文件,把module原内容转换成新的
plugin注入钩子:webpack构建过程中广播对应事件,插件可以监听这些事情的发生
最后输出模块化的组合(chunk),一个chunk由多个module组成

·获取初始化参数:shell命令行+配置文件
开始编译:上一步得到参数初始化Compiler对象,加载所有配置的插件,通过执行run开始执行编译
确定入口:根据配置中的entry
编译模块:从入口出发,调用所有配置的Loader对模块进行翻译
解决依赖:具体的方法看webpack采用的模块机制,common.js、AMD、ESM
输出资源:根据依赖将多个module打包成一个chunk,再将其转换为文件加入输出列表。
完成输出:根据配置文件,输出到对应目录

Compiler对象负责监听文件、启动编译
模块依赖:apply函数传入module.export对象
loader的apply方法传入Compiler对象
好处

  • 将许多碎小文件打包成一个整体,减少单页面内的衍生请求次数,提高网站效率
  • 将ES6的高级语法进行转换编译,以兼容老版本的浏览器
  • 将代码打包的同时进行混淆,提高代码的安全性。
  • 将模块化、或者支持其他先进语法的代码转译为浏览器可以运行的。

单页应用的流行,网页的功能和实现代码变得复杂、庞大、web开发向模块化进发

相比不打包直接浏览器运行,模块的依赖关系完全由文件的加载顺序决定,而webpack有优化措施

常见构建工具

构建:将源代码转换为可执行的JavaScript、css、HTML代码。
主要包括:代码转换(ts->js、scss->css等)、文件优化、代码分割、模块合并、自动刷新(监听本地源代码的变化,自动重新构建、刷新浏览器)、代码校验、自动发布。
换一种说法:验证JavaScript语法、CSS压缩、Sass编译等

Npm Script

任务执行者,允许在package.json文件里使用script字段定义任务
内置在Node.js中,无需依赖;但是功能过于简单。
提供了pre、和post两个钩子

补充:
package.json 中版本号 ^ 和 ~
波浪符号:~1.15.2,库会去匹配更新到1.15.x的最新版本,但是他不会自动更新到1.16.0
插入符号:^3.3.4,库会去匹配3.x.x中最新的版本,但是他不会自动更新到4.0.0。

语义版本号分为X.Y.Z三位,分别代表主版本号、次版本号和补丁版本号。当代码变更时,版本号按以下原则更新。
如果只是修复bug,需要更新Z位。
如果是新增了功能,但是向下兼容,需要更新Y位。
如果有大变动,向下不兼容,需要更新X位。

Grunt

有大量的插件封装了常见的任务,也能管理任务之间的依赖关系,自动化执行依赖的任务。写在配置文件Gruntfile.js里
集成度不高,需要写很多配置,无法做到开箱即用。相当于进阶版Npm

Gulp

基于流的自动化构建工具。
管理、执行任务,还支持监听文件、读写文件。只需要通过以下五个方法基本可以支持所有构建场景。

  • gulp.task注册任务
  • gulp.run执行任务
  • gulp.watch监听文件变化
  • gulp.src读取文件
  • gulp.dest写文件
    同时提供了一堆插件去处理流,流可以在插件之间传递
    Grunt的加强版,增加一些功能,但是仍然集成度不高,需要写很多配置,无法做到开箱即用。

Fis3

百度的优秀国产构建工具

Webpack

实践一个最简单的webpack

(1)新建文件夹之后 init一个web项目
生成package.json文件(配置NPM以使我们能够下载JavaScript包:开发、生产使用)

以webpack为例,使用下载的JavaScript包,还需要再建立一个JavaScript文件 webpack.config.js,描述其使用,文件中require语法引入包

区别于typescript,项目根目录下tsconfig.json输入文件列表以及编译选项(这是单独使用typescript情况,不是与webpack并用,并用时候在webpack.config.js中module里引入rules)

在这里插入图片描述
管理依赖项:dependencies、devDependencies、peerDependencies
dependencies include utility libraries such as lodash, classnames etc and also the “main” libraries of your project.
peerDependencies : react, react-dom, styled-components, etc

devDependencies:
formatting libraries: eslint, prettier, …
bundlers: webpack, gulp, parceljs, …
babel and all its plugins
everything related to tests: enzyme, jest, …
a bunch of other libraries: storybook, react-styleguidist, husky, …

git submodule,git submodule很容易造成一个环境里多版本共存,更容易触发问题。

A文件中的devDependencies,对应开发A时候添加依赖包时候的npm i -D
当我们的包在开发时依赖另一个包的时候,我们应该把他们作为devDependencies来安装,这样他们就不会污染模块使用者的node_modules。后面实际执行用不到,所以不需要下载。npm i A不会下载devDependencies部分
不加-D时候是添加到dependencies

"devDependencies": {
    "@types/node": "^15.6.0",
    "typescript": "^4.2.4",
    "webpack-dev-server": "^3.11.2",
    "gulp": "3.9.0",
    "del": "2.2.0"
  },
  "dependencies": {
    "webpack-cli": "^4.7.0"
  }

保存这个文件后,IDE将自动开始安装gulp和del。 若没有,请右击package.json文件选择Restore Packages。

peerDependencies的目的是提示宿主环境去安装满足插件peerDependencies所指定依赖的包,然后在插件import或者require所依赖的包的时候,永远都是引用宿主环境统一安装的npm包,最终解决插件与所依赖包不一致的问题。A的peerDependencies会和B一起被下载
适用于同一个页面中只出现一个版本或一个实例的npm包

注意:NPM3反对同行的依赖(peer dependencies)

(2)安装webpack到本地项目
注意区分系统全局安装和局部安装

npm i -g webpack//全局
npm i -D webpack//局部   等同于package.json里面的devDependencies?
//通过@指定版本
npm i -D webpack@<version>//局部

推荐局部安装到本项目,原因是可防止不同项目以来不同版本的webpack而导致冲突

生成了node_module文件夹

在这里插入图片描述
注意webpack命令的有效地址和npm命令
在这里插入图片描述

(3)运行构建前需要将入口的HTML和JavaScript文件建立好
webpack.config.js(webpack执行构建会从该文件读取配置)文件如下

'use strict';
const path=require('path');
module.exports={
 entry:'./src/index.js',                 //打包文件路径
 output:{
    path:path.join(__dirname,'dist'),   //输出文件路径
    filename:'bundle.js'                //输出文件名
 },
 mode:'production'
};

规范地新建一个src文件夹
文件夹中新建index.js和hello.js文件(Webpack 本身只能处理 JavaScript 模块,这里我们还不引入loader)

在这里插入图片描述

(4)然后执行webpack命令构建,这里自己添加了一个npm script命名
在这里插入图片描述

生成dist文件夹
webpack是一个打包模块化JavaScript的工具,会从index.js出发,识别出源码中模块化导入语句,递归找出入口文件所有依赖,将所有依赖和入口打包到一个单独的文件中即./dis/bundle.js

在这里插入图片描述

//bundle.js
(()=>{"use strict";document.write("hello webpack")})();

基础

配置

配置方式

  1. 执行Webpack可执行文件时候,加入命令行参数(本质)
  2. webpack.config.js文件描述配置 --config webpack.config.js

注意一部分配置只能通过 webpack.config.js文件进行配置

配置项目

1、Entry模块的入口

context作为查找相对路径的根目录
entry:可以是字符串、数组、对象、函数。前两者只会生成一个 “main” chunk。对象则会生成以键为名的多个chunk。

动态Entry:异步、同步
项目有多个页面且每个页面都有一个入口,且入口数还在不断增多

entry:()=>{
	return {
		a:'./pages/a',
		b:'./pages/b',
	}
};

entry:()=>{
	return new Promise((resolve)=>{
		resolve({
			a:'./pages/a',
			b:'./pages/b',
	});
	});
};

2、output输出配置对象

output是一个对象,属性是配置如何输出最终想要的代码的配置项

output包含输出配置的对象

输出文件名

有入口的chunk的output
output. filename, 用string写死

当多个Chunk,根据chunk的标识来区分输出文件

filename:'[ name ]. js'
filename:'[ hash:8 ]. js' 可以指定hash值的长度

无入口的chunk的output
chunkFilename只用于在运行中生成的chunk

即使用CommonChunkPlugin、使用import动态加载等的情况

内置变量

变量名含义
idchunk的唯一标识,从0开始
name
hashchunk的唯一标识的hash值
chunkhashchunk内容的hash值

输出的路径

output. path输出文件放在本地的位置,string类型的绝对路径
一般通过node.js的path模块去获取绝对路径。webpack运行在node.js环境

异步加载的资源

webpack打包复杂项目时候,可能会有构建出的资源需要异步加载,就要把资源放在线上资源的对应的URL地址

发布到线上的html文件使用jsonp引入异步加载资源 url+ filename
涉及异步加载
output. crossOriginLoading配置异步插入的Script标签的crossorigin值

anonymous加载资源不会带上用户的cookie
use-credentials带cookie

构建导出库

构建被其他模块导入使用的库,搭配使用libraryTarget、library

library导出库的名称

libraryTarget配置以什么方式导出库,字符串的枚举类型。
导出的库可以支持多种配置导入:

var
commonJS方式导入使用
commonJS2
this
window
global

output.library=‘Name’
lb_code是指导出库的代码内容,那输出和使用

// var
// webpack输出代码
var Name=lb_code;
// 使用库的方法
Name.doSomething();
// commonJS方式导入使用 
exports['Name']=lb_code;
require('library-name-in-npm')['Name'].doSomething();
// commonJS2
module.exports=lb_code;
require('library-name-in-npm').doSomething();
// this
this['Name']=lb_code;
this.Name.doSomething();
// window
window['Name']=lb_code;
window.Name.doSomething();
// global
global['Name']=lb_code;
global.Name.doSomething();

commonJS、commonJS2方式导入使用的时候,可以配置要导出的子模块

module.exports=lb_code['a'];
require('library-name-in-npm')===1;

3、Module配置处理模块的规则

rules

loader处理源文件

loader:用于资源加载并处理各种语言的转换/编译(例如将不同语言转换为javascript),导出一个函数——对资源文件进行处理后输出内容,类似于管道。
可以串联多个 loader,将返回值交给下一个 loader 继续处理

webpaack是运行在node之上的,一个loader就是一个node模块,这个模块需要导出一个处理函数。webpack也为loader提供了一些可以调用的API,例如source map,处理文件的上下文
根据应用场景,loader有同步异步之分,具体体现在内部实现上

写好的loader一般发布到远程npm,然后下载源码到node_module下面

选中文件+use

Webpack 本身只能处理 JavaScript 模块,如果要处理其他类型的文件,就需要使用 loader 进行转换。
css文件

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

原理:将CSS的内容用JavaScript里的字符串存储起来,在网页执行JavaScript时通过DOM操作,动态地向HTML的head标签中插入style标签。

然后配置webpack.config.js文件,增加modules中的规则
实现针对性的规则配置

'use strict';
const path=require('path');
module.exports={
 entry:'./src/index.js',                 //打包文件路径
 context:
 output:{
    path:path.join(__dirname,'dist'),   //输出文件路径
    filename:'bundle.js'                //输出文件名
 },
 mode:'production'
 modules:{
 	rules:[
		//正则匹配到以css结尾的文件使用下面的loader
		test:/\.css$/,
		use:['style-loader','css-loader']
	]
}
};

通过test、include、exclude三个配置项来选中Loader要应用规则的文件,除了正则表达式,也支持正则表达式的数组,数组各项代表|或
默认处理顺序是从后往前,先交给css-loader
可以通过enforce选项可以将一个loader的执行顺序提到最前pre,或者最后post

这样做会导致JavaScript文件变大且网页加载时间变长,可以通过webpack Plugin机制来实现单独输出CSS文件

图片文件也有file-loader

parse与noParse

noParse配置项可以让webpack忽略对没有采用模块化的文件的递归解析和处理,可以提高构建性能。
因为例如jQuery、chartjs等庞大又没有采用模块化标准(不含import、require、define,可以直接在浏览器中运行),解析他们耗时有没有意义

parse可以更细粒度地控制哪些模块语法被解析,精确到语法层面

parse:{
	amd: false, // 禁用
	commjs: false,
	system: false,
	harmony: false, // 禁用ES6 import/export
	browserify: false,
}

因为webpack是以模块化JavaScript文件为入口的,所以内置了对模块化JavaScript的解析功能。

4、resolve寻找模块所对应的文件

配置webpack如何寻找模块所对应的文件

alias 文件路径简写

import Utility from '../../utilities/utility';
import Utility from 'Utilities/utility'; // 使用别名
alias: {
  Utilities: path.resolve(__dirname, 'src/utilities/'),  // 用Utilities代替后面的路径
}

可以在给定对象的键后的末尾添加 $,以表示精准匹配以xyz结尾的导入语句

alias: {
  xyz$: path.resolve(__dirname, 'path/to/file.js')
}

mainFields 找取适合的代码

有些第三方库会针对不同的环境提供几份代码(ES5、ES6…),那么webpack在打包import导入的第三方包的时候会根据mainFields的顺序去选取导入的文件

mainFields: ["browser", "module", "main"]

查看第三方包的package.json 含有这些字段:

{
  ...
  main: 'build/d3.Node.js',
  browser: 'build/d3.js',
  module: 'index',
  ...
}

extensions 导入文件的文件后缀

自动加入导入文件的文件后缀

extensions: [".js", ".json"]

先找file.js再找file.json

import File from '../path/to/file'

modules 配置查找第三方库的目录

webpack默认到node_module下查找

modules: ["node_modules"]

如果添加一个目录到模块搜索目录,此目录优先于 node_modules/ 搜索

modules: ['./src/components', "node_modules"]

import ‘./src/components/button’ import ‘.button’

5、plugins扩展功能:作用于整个构建过程

plugins是一个plugin数组
plugin:用于资源加载以外的其他打包/压缩/文件处理等功能
是一个函数,或者包含apply方法的对象:
apply 方法有一个参数 compiler,通过 compiler 可以给 webpack 编译打包过程中添加钩子
构造函数里面挂载两个结果回调函数,done、fail

通过钩子的回调函数 callback 拿到打包结果对象 compilation(通过compilation.assets 获取资源文件信息),然后对打包结果对象 compilation 进行修改

使用

模块加载器
扩展webpack功能,通过在构建流程中注入钩子函数来实现,几乎所有webpack无法实现的功能都可以找到开源的plugin解决。
涉及webpack.config.js文件的内容。
webpack运行中设计很多事件,plugin可以监听这些事件,在特定的时刻调用webpack提供的API
来实现对webpack现有功能的扩展,比如打包优化、文件压缩功能。

上面提到的输出单独的CSS文件

'use strict';
const path=require('path');
module.exports={
 entry:'./src/index.js',                 //打包文件路径
 output:{
    path:path.join(__dirname,'dist'),   //输出文件路径
    filename:'bundle.js'                //输出文件名
 },
 mode:'production'
 modules:{
 	rules:[
		//正则匹配到以css结尾的文件使用下面的loader
		test:/\.css$/,
		use:['style-loader','css-loader']
	],
	plugins:[
		new ExtractTextPlugin({
			filename: `[name]_[contenthash:8].css`
		}),
	]
}
};

然后安装新引入的插件

npm i -D extract-text-webpack-plugin

npm下载、require语法导入、webpack.config.js的plugins数组中配置注册

部分需要快速执行命令的,在package.json中注册script

plugins属性是一个数组,里面的每一项都是插件的一个实例,在实例化一个组件时可以通过构造函数传入这个组件支持的配置属性。

DevServer

启动一个HTTP服务器用于启动webpack,服务网页请求,并接收webpack发出的文件更变信号,通过webSocket协议自动刷新网页做到实时预览。
先安装:

npm i -D webpack-dev-server

开启后控制台显示:
project is running at http://localhost:8080/
访问这个网址就能获取项目根目录下的index.html文件
而生成的bundle.js的网址是 http://localhost:8080/bundle.js,所以需要在index.html文件中script引入bundle.js

监听的实现:DevServer会让webpack在构建出的JavaScript代码里注入一个代理客户端用于控制网页,网页和DevServer通过webSocket通信,DevServer在收到来自webpack的文件变化通知时,通过注入的客户端控制网页刷新。inline配置

来自webpack的文件:即entry本身和依赖的文件才会被webpack添加到监听列表里。上述index.html文件是脱离JavaScript模块系统的,不会被webpack探索到。

devServer.hot 模块热替换

默认会自动刷新整个页面来做实时预览
模块热替换:不重新加载整个网页的情况下,局部更新,默认关闭
启动DevServer的时候带上–hot参数
或者dev.Server.hot配置

devServer.inline代理客户端自动注入

实时预览功能依赖一个注入页面的代理客户端,取接收来自devServer的命令并刷新网页的工作。
devServer.inline配置是否将这个代理客户端自动注入将运行在页面中的chunk
不开启devServer.将无法直接控制要开发的网页,这时他会通过刷新iframe来实时预览

常用命令的背后

即package.json文件中的script

npm run dev

执行dev-server.js文件,关于该文件的了解看
使用express、http-proxy-middleware代理的中间件等实现本地服务器的搭建,注意这里是负责模拟后台的数据
==和webpack-dev-server到底有什么区别和联系?==好像会混用

webpack-dev-server

webpack官方提供的一个小型Express服务器。
webpack-dev-server 主要为静态文件提供web服务以及自动刷新和热替换(HMR)
通过websocket协议来告知浏览器更新文件,以实现实时的预览。

编辑src中的代码,保存后浏览器端会实时自动刷新。LiveReload技术

npm run build

执行build.js文件,控制编译过程

webpack与vue

目前主流的前端开发框架都采用webpack作为工程化工具

vue是框架,而webpack是打包工具,注意区别。
vue官方提供了一个快速搭建vue项目的脚手架:vue-cli,使用它能快速的构建一个web工程模板。
vue-cli里面默认继承了express、webpack.
快速体验一下vue-cli
在这里插入图片描述
?没有在总目录下看到package.json,查找之后每个模块下面有一个??
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值