关于webpack(webpack 4.0版本)

查看版本:webpack -v

一、什么是webpack?

可以看做是模块打包机(一种模块化的解决方案)也是一个打包工具。

二、webpack的工作方式

把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件。

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

image.png

三、webpack相关文件

package.json文件:npm说明文件,里面蕴含丰富信息,包括当前项目的依赖模块,自定义的脚本任务。

在终端使用npm init命令可以自动创建这个package.json文件(输入这个命令后,终端会问你一系列诸如项目名称,项目描述,作者等信息node,如果你不准备在npm中发布你的模块,这些问题的答案都不重要,回车默认即可)

四、webpack的安装

package.json文件就绪后,在项目中安装Webpack作为依赖包

npm install -g webpack                //全局安装
npm install --save-dev webpack       //安装到你的项目目录

npm info webpack    可以查看webpack版本信息

运行过程中如果出现:webpack:command not found,请检查是否在全局环境下安装webpack,全局环境下安装webpack使用命令:npm install webpack -g

不推荐全局安装 webpack。这会将你项目中的 webpack 锁定到指定版本,并且在使用不同的 webpack 版本的项目中,可能会导致构建失败。 ---来自webpack官网

五、webpack搭建

1.npm install webpack --save-dev
2.npm init   //初始化package.json文件
3.npm install webpack-cli --save-dev   //CLI(命令行工具)已经转移到了一个单独的包webpack-cli中。 
4.创建src目录并新建index.js  写入一段代码。 //webpack4.x默认是以项目根目录下的'./src/index.js'作为入口,因此我们在根目录下创建src文件夹。
  function hello(str) { alert(str); } 
  hello('hello world!');
5.输入webpack --mode development命令或者webpack --mode production命令打包   //就可以将'./src/index.js'打包成'./dist/main.js'。 
# 注意:webpack4.x的打包已经不能用webpack 文件a 文件b的方式,例如:webpack index.js bundle.js 命令
# 而是直接运行webpack --mode development或者webpack --mode production,这样便会默认进行打包,
# 入口文件是'./src/index.js',  输出路径是'./dist/main.js',
# 其中src目录即index.js文件需要手动创建,而dist目录及main.js会自动生成。 
6.不过每次都要输入这个命令,非常麻烦,我们在package.json中scripts中加入两个成员:
"dev":"webpack --mode development", 
"build":"webpack --mode production"
之后运行 npm run dev即可打包
7.配置其他参数
在webpack –mode production/development后加上其他参数即可例如:
webpack --mode development --watch --progress --display-modules --colors --display-reasons
当然,这也可以写入package.json的scripts之中。

六、webpack中的各种loader

1.什么是loader

用法参考:https://webpack.docschina.org/concepts/loaders/#
Loader 可以理解为是模块或资源的转换器,它本身是一个函数,接受源文件作为参数,返回转换的结果。这样,我们就可以通过 require 来加载任何类型的模块或文件,比如 CoffeeScript、 JSX、 LESS 或图片。

  • loaders是你用在app源码上的转换元件。他们是用node.js运行的,把源文件作为参数,返回新的资源的函数。
  • loader是文件加载器,能够加载资源文件,并对这些文件进行一些处理,诸如编译、压缩等,最终一起打包到指定的文件中
  • 处理一个文件可以使用多个loader,loader的执行顺序是和本身的顺序是相反的,即最后一个loader最先执行,第一个loader最后执行。
  • 第一个执行的loader接收源文件内容作为参数,其他loader接收前一个执行的loader的返回值作为参数。最后执行的loader会返回此模块的JavaScript源码

2.loader的安装:npm install xxx-loader -save-dev

3.loader的三种用法:

①require() (可以在 require() 引用模块的时候添加)

a.在hello.js中通过require引用style.css,执行webpack hello.js hello.bundle.js,报错如下图:


image.png

报错信息

报错提示需要一个loader转换器来处理css样式

b.输入命令:npm install css-loader style-loader --save-dev,来安装css的loader转换器和style的loader转换器
安装完成后,输入命令:webpack hello.js hello.bundle.js,进行编译hello.js
s运行发现仍然发现报错


image.png

c.查看引入style.css的地方,webpack只能处理javascript模块,处理css需要借助于loader转换器
在require() 引用模块的时候添加loader转换
那么在require引入style.css文件时,就需要css-loader转换。require('css-loader!./style.css');


image.png

在进行编译打包hello.js,编译打包成功


image.png

查看hello.bundle.js文件,多出了css样式这一块,并且css样式为一独立模块


image.png

d.在项目目录下新建一个index.html,并且引入hello.js打包后的hello.bundle.js


image.png

e.修改hello.js,运行hello()函数,接着再编译一次hello.js到hello.bundle.js


image.png

image.png

f.运行index.html,页面上弹出“hello world!”
j.但是我们发现页面的背景色并没有变成ccc的样式,要想让css样式生效,还需要在require引入css的时候使用style-loader
require('style-loader!css-loader!./style.css');
编辑完后再用webpack编译打包


image.png

image.png

h.刷新index页面,页面变成了ccc的背景色

image.png

发现style.css中的样式被使用style标签插入到了head里面,这是由style-loader实现的
css-loader是允许webpack识别.css的文件
style-loader是将webpack识别完的css文件中的内容,在编译完运行文件的时候,将这些css用style标签包起来嵌在head内
上面的例子讲述的都是在require引入模块的时候添加的loader转换,还有一种方式就是在命令行中添加loader,其他和上面讲述一样

②在配置文件webpack.config.js中通过module.loaders进行配置 (可以在 webpack 全局配置中进行绑定)
③在命令行中配置 (可以通过命令行的方式使用)

在命令行中添加loader
在命令行中输入命令:webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader'
(git bash中执行相当于linux,如在windows下的cmd估计要将单引号换成双引号)
去掉hello.js中require时添加的loader依赖,并将上面的命令进行编译

image.png

image.png

每次修改完文件进行编译时都需要写命令,很是繁琐,在命令最后加上--watch,当文件有变化时,就会自动编译
webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --watch
image.png

当修改hello.js文件保存后,就会看到命令行上已经重新编译
image.png

刷新index.html就可以看到修改后的内容了

七、webpack其他命令介绍:

--progress:当前打包的进度条
--display-modules:打包的模块,依赖什么而打包也会列出来
--display-reasons:打包模块的原因,因为什么打包
输入完整命令:webpack hello.js hello.bundle.js --module-bind 'css=style-loader!css-loader' --progress --display-modules --display-reasons --watch
当检测到文件有变化时进行编译,编译输出包括打包进度、打包模块、打包原因


image.png

congratulation到这里,loader的使用已经开始入门了!

八、package-lock.json到底是干嘛的?

原来package.json文件只能锁定大版本,也就是版本号的第一位,并不能锁定后面的小版本,你每次npm install都是拉取的该大版本下的最新的版本,
npm最新的版本开始提供自动生成package-lock.json功能

package-lock.json锁定依赖包版本,当用户在另外一台电脑或者新环境下,只要按照package-lock.json所标示的具体版本下载依赖库包,就能确保所有库包与你上次安装的完全一样。

这里举个例子:
"dependencies": {
"@types/node": "^8.0.33",
},
这里面的 向上标号^是定义了向后(新)兼容依赖,指如果 types/node的版本是超过8.0.33,并在大版本号(8)上相同,就允许下载最新版本的 types/node库包,例如实际上可能运行npm install时候下载的具体版本是8.0.35

那如果我们安装时的包有bug,后面需要更新怎么办?
在以前可能就是直接改package.json里面的版本,然后再npm install了,但是5版本后就不支持这样做了,因为版本已经锁定在package-lock.json里了,
所以我们只能npm install xxx@x.x.x 这样去更新我们的依赖,然后package-lock.json也能随之更新。

注意:在直接更新package.json和package-loc.json这两个文件后,npm install是可以直接覆盖掉原先的版本的,所以在协作开发时,这两个文件如果有更新,你的开发环境应该npm install一下才对。

九、前端工程项目的NODE_ENV

在package.json的scripts命令内容和webpack配置文件中可以看到NODE_ENV这个变量,它的值可以是development或product,也有人简写为'dev'或'prod'。
这个变量表示构建项目的当前环境,也就是我们的程序会跑在生产环境、测试环境还是开发环境,
node中有全局变量process表示当前node进程,process.env包含着关于系统环境的信息。但是process.env中并不存在NODE_ENV这个东西。其实NODE_ENV只是一个用户自定义的变量。
当我们在服务启动时配置NODE_ENV,或在代码中给process.env.NODE_ENV赋值,js便能通过process.env.NODE_ENV获取信息。
那么,这个变量的赋值在哪里设置呢?很多开发者将NODE_ENV=XXXX放到项目package.json的scripts命令中:

"scripts": {
    "build-win": "SET NODE_ENV=production && webpack --config build/webpack.config.js",
    "build": "EXPORT  NODE_ENV=production && webpack --config build/webpack.config.js"
 }

也有人会在webpack配置文件中对NODE_ENV作默认值处理,如果scripts.build||script.start脚本没有设置NODE_ENV,缺省值为'development'.
NODE_ENV: process.env.NODE_ENV || 'development',
不同平台下的设置区别?
在类unix系统和安装并使用了bash的windows的系统上,我们会使用:

"EXPORT  NODE_ENV=production && webpack --config build/webpack.config.js"

在windows系统上,我们使用:

"SET NODE_ENV=production && webpack --config build/webpack.config.js"

有的人嫌麻烦,为了屏蔽两种系统间的这个区别,会引用第三方插件cross-env

{
  "scripts": {
    "build": "cross-env NODE_ENV=production webpack --config build/webpack.config.js"
  }
}

只要在NODE_ENV前面加上cross-env标志,会根据当前系统类型帮你选择适当的指令给NODE_ENV赋值。

mode选项:
在mode为production或development的状态下,为了兼顾两个状态下的程序运行,webpack创建了一个全局变量process.env.NODE_ENV,等同于在插件plugins中加入了

new webpack.DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("development|production") })

用来区分不同的状态,同时可以在程序中区分程序状态。
那么我们该如何在coding的时候进行区分呢?因为process.env.NODE_ENV是全局变脸给,所以可以这样来引用值,假设mode:production:

if ("development" === process.env.NODE_ENV){ .... }else{ .... }

编译之后:

if ("development" === "production"){ .... }else{ .... }

也就是最后process.env.NODE_ENV会被替换为一个常量。这个小功能可以帮助我们在写业务JS的时候,区分线上版本与开发版本。

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

推荐阅读更多精彩内容