目录
webpack(module bundler,模块打包器)
webpack(module bundler,模块打包器)简介
由来:由于前端之前js、css、图片等文件需要单独进行压缩和打包,这样团队人员处理很繁琐,Instagram团队就想让这些工作自动化,然后webpack应运而生
webpack是一个模块打包器(module bundler),webpack视HTML、JS、CSS、图片等文件都是一种资源 ,每个资源文件都是一个模块(module)文件,webpack就是根据每个模块文件之间的依赖关系将所有的模块打包(bundle)起来
webpack是前端的一个项目构建工具,它是基于Node.js开发出来的一个前端工具,借助于webpack这个前端自动化构建工具,可以完美实现资源的合并、打包、压缩、混淆等诸多功能
注意:因为webpack一些插件总是不断更新,所以在工作中建议用vue脚手架生成
webpack安装
安装webpack首先需要安装Node.js,Node.js自带了软件包管理工具npm
1.本地(局部)安装:npm install [–save,–save-dev] webpack
①最新版本:npm install --save-dev webpack
②指定版本:npm install --save-dev webpack@<version>
是否使用–save-dev取决于用例。假设仅使用webpack进行捆绑,那么建议将其安装为–save-dev选件,因为不会在生产版本中包含webpack。否则,可以忽略–save-dev
注意:如果使用的是webpack v4或更高版本,则还需要安装CLI
npm install --save-dev webpack-cli
(1)–save:生产环境
将配置信息保存到package.json中,同时–save:也是项目生产环境,项目发布之后还依赖的东西,保存在dependencies
例如:如果用了jQuery,由于发布之后还是依赖jQuery,所以是dependencies
(2)–save-dev:开发环境
项目开发环境依赖的东西,项目打包后不需要继续使用。保存在devDependencies中
2.全局安装:npm install --global webpack
以下NPM安装将在webpack全球范围内可用:
npm install --global webpack
注意:这不是推荐的做法。全局安装会限制使用特定版本webpack,并且在使用其他版本的项目中可能会失败
重点(★)
对于大多数项目,建议在本地安装。引入重大更改后,这使得单独升级项目变得更加容易。通常,webpack通过一个或多个npm脚本运行,这些脚本将在本地node_modules目录中查找webpack安装
"scripts": {
"build": "webpack --config webpack.config.js"
}
要运行webpack的本地安装,可以访问的二进制版本node_modules/.bin/webpack。另外,如果使用的是npm v5.2.0或更高版本,则可以运行“npx webpack”来执行
全局安装和局部文件安装区别
1.全局安装
全局安装方式是键入命令
npm install webpack -g
或
npm install webpack --global
安装位置
包安装在Node安装目录下的node_modules文件夹中,一般在 \Users\用户名\AppData\Roaming\ 目录下,可以使用npm root -g查看全局安装目录
调用方式
全局安装后可以供命令行(command line)使用,用户可以在命令行中直接运行该组件包支持的命令
2.本地(局部)安装
本地安装方式是键入命令
npm install webpack
或
npm install webpack --save-dev
安装位置
其中参数–save-dev的含义是代表把安装包信息写入package.json文件的devDependencies字段中,包安装在指定项目的node_modules文件夹下
补充:
npm install module_name -S即npm install module_name --save;写入dependencies
npm install module_name -D即npm install module_name --save-dev;写入devDependencies
dependencies与devDependencies的区别:
package.json字段 | 描述 |
---|---|
devDependencies | 只用于开发环境,不用于生产环境 |
dependencies | 需要发布到生产环境 |
举个例子:开发一个前端项目,在项目中需要使用gulp构建你的开发和本地运行环境,这时就要放到dependencies里。gulp是用来压缩代码,打包等需要的工具,程序实际运行的时候并不需要,所以放到dev里就ok了
调用方式
本地安装后可以直接通过require()的方式引入项目中node_modules目录下的模块,如下示例,本地安装后直接在webpack.config.js中require(‘gulp’)
为什么全局安装还要本地安装?仅仅全局安装够吗?
一个项目往往依赖特定的webpack版本,全局版本可能与项目的webpack版本不一致,导致导出打包出现问题,所以,一个项目通常都需要自己的局部webpack
1.在js实例代码中,默认下node.js会在NODE_PATH和目前js所在项目下的node_modules文件夹下去寻找模块,因此,如果只是全局安装,不能直接通过require()的方式去引用模块,需要手动解决包路径的配置问题
①当然也可以复制全局安装的node_modules文件夹到项目下
②还有办法可以选择将环境变量的NODE_PATH设置为C:\Program Files\nodejs
2.对于包的更新不好管理,可能需要为每个包重新命名,如gulp@3.8.1、gulp@3.9.1…,为了区别不同项目使用指定的包,保证模块之间的相互依赖,区别每个项目正常运行
3.在终端直接执行webpack命令,使用的全局安装的webpack;当在package.json中定义了scripts时,其中包含了webpack命令,那么使用的是局部webpack
综上所述,不推荐只全局安装
本地安装的重要性
最早的node.js/npm实际上是全局的,包括现在还兼容NODE_PATH,但是不能支持全局多版本,于是nodejs团队改成本地安装的方法可能就是为了保证不同版本包之间的相互依赖
其中依赖包的指定版本号,不可轻易去修改,因为不同版本包对应依赖包的版本的功能有所差别,如果修改指定的版本来运行demo,就可能会编译出错等bug
例子:
包版本为:A(0.0.1)依赖B(0.0.2),B(0.0.1)依赖C(0.0.3)
一段时间原作者更新后
包版本为:A(1.0.1)依赖B(1.0.0),B(1.0.0)依赖C(1.0.0)
每一次的更新可能带来不一样的功能,在多人合作、发布模块到npmjs社区、上传到github给其他人使用时,保留模块的版本信息可用于下载指定的版本号显得特别重要。
本地安装可以让每个项目拥有独立的包,不受全局包的影响,方便项目的移动、复制、打包等,保证不同版本包之间的相互依赖,这些优点是全局安装难以做到的。
另外,据node团队介绍,本地安装包对于项目的加载会更快。
有优点也少不了缺点,如每次新项目都要本地安装所依赖的包,安装包时间相对较长,一来是包太大导致下载慢;二是浪费了硬盘空间,不过现在电脑硬盘动不动就几个T,还会在意节省这点空间吗?
webpack作用?
(1)对CommonJS、AMD、CMD、ES6等语法做了兼容
(2)对js、css、图片等资源文件都支持打包(适合团队化开发)
比如:写一个js文件,另外一个人也写一个js文件,需要合并很麻烦,现在交给webpack合并很简单
(3)有独立配置文件webpack.config.js
可以将代码切割成不同的chunk(块),实现按需加载,降低了初始化时间
(4)具有强大的Plugin(插件)接口
大多是内部插件,使用起来比较灵活
webpack和gulp区别
(1)grunt/gulp(前端自动化构建工具)
强调的是前端开发的工作流程,可以通过配置一系列的task,定义task处理的事情(代码压缩、合并、编译、浏览器实时更新等),然后定义执行顺序,来让gulp执行这些task,从而构建项目的整个前端开发流程,自动化构建工具并不能把所有模块打包到一起,也不能构建不同模块之间的依赖关系
grunt/gulp核心(Task)
配置一系列的task,并且定义task要处理的事务(ES6、ts转化、图片压缩、scss转成css)
让grunt/gulp来依次执行这些task,而且让整个流程自动化
grunt/gulp也被称为前端自动化任务管理工具
例子task:将src下面的所有js文件转成ES5的语法,并且最终输出到dist文件夹中
const gulp = require("gulp")
const babel = require("gulp-babel")
gulp.task(
'js',() => gulp.src("src/*.js")
.pipe(bebal({presets:[ 'es2015']}))
.pipe(gulp.dest('dist'))
);
什么时候使用grunt/gulp?
如果工程模块依赖非常简单,甚至没有用到模块化的概念;只需要进行简单的合并、压缩,就可以使用grunt/gulp即可
如果整个项目使用了模块化管理,而且相互依赖非常强,就可以使用更加强大的webpack
(2)webpack(JavaScript应用程序的模块打包器)
强调的是一个前端模块化方案,更侧重模块打包,可以把开发中的所有资源(图片、js文件、css文件等)都看成模块,通过loader(加载器)和plugins(插件)对资源进行处理,打包成符合生产环境部署的前端资源
目录 | 描述 |
---|---|
src | 代码开发目录 |
build | 开发环境webpack编译打包输出目录,同样按照view、styles、js组织 |
dist | 生产环境webpack编译打包输出目录,同样按照view、styles、js组织 |
node_modules | 所以使用的node.js模块 |
package.json | 项目配置 |
webpack.config.js | 开发环境webpack配置 |
webpack.production.config.js | 生产环境webpack配置 |
grunt/gulp与webpack有什么不同?
grunt/gulp:更加强调的是前端流程的自动化,模块化不是它的核心
webpack:更加强调模块化开发管理,而文件压缩合并、预处理等功能,是它附带的功能
webpack五个核心概念
(1)Entry:入口
入口(Entry)指示Webpack以哪个文件作为入口起点分析构建内部依赖图并进行打包
(2)Output:出口
输出(Output)指示Webpack打包后的资源bundles输出到哪里去,以及如何命名
(3)Loader:(加载器)加载非JavaScript文件
Loader让Webpack能够去处理那些非JavaScript语言的文件,Webpack本身只能理解JavaScript
(4)Plugins:插件
插件(Plugins)可以用于执行范围更广的任务,插件的范围包括从打包和压缩,一直到重新定义环境中的变量等
(5)Mode:开发模式
模式(Mode)指示Webpack使用相应模式的配置。分为development和production两种模式
①development:开发模式
能让代码本地运行的环境,会将process.env.NODE_ENV的值设为development,同时启用NamedChunksPlugin和NamedModulesPlugin插件
②production:生产模式
能让代码优化运行的环境,会将process.env.NODE_ENV的值设为production,同时启用FlagDependencyUsagePlugin、FlagIncludedChunksPlugin、ModuleConcatenationPlugin、
NoEmitreplaceStringsPlugin、OccurrenceOrderPlugin、SideEffectsFlagPlugin和UglifyJsPlugin插件