目录
关于打包的疑问?grunt/gulp与webpack之间的区别?
4.2.1.css-loader(style-loader)
4.2.2.less-loader(scss、stylus)
5.2.2.vue-loader vue-template-compiler
6.3.3.uglifyjs-webpack-plugin(丑化代码)
一、webpack是什么?
官方解释:webpack是一个现在的JavaScript应用的静态模块打包工具
模块:就是模块化
打包:我们在开发时,是有很多文件,如果直接发给浏览器,浏览器对其不支持的语言就无法解析,导致最后不能显示,或显示错误。
webpack则是可以对代码进行转化打包,生成一个最终的浏览器可以识别的代码
前端模块化:
1.webpack会提供一种支撑,来自动解析AMD,CMD,commonJS,ES6等,将之转化成大部分浏览器能识别的方案,最终打包成的代码中是没有所谓的AMD,CMD,commonJS,ES6代码,但是我们可以使用这些来开发,来让webpack来打包
2.在ES6之前,我们要想进行模块化开发,就必须借助于其他的工具,让我们可以进行模块化开发。并且在通过模块化开发完成项目后,再去处理模块间的各种依赖,并且将其进行整合打包
3.webpack的其中一个核心,就是模块化。它可以帮助我们处理模块间的依赖关系 不仅仅是JavaScript文件,我们的CSS,图片,json文件等都可以在webpack当作模块使用,这就是webpack中模块化的概念。
打包:
1.打包就是把各种资源模块进行打包合并成一个或多个包(Bundle),而我们可以使用webpack来打包。
2.在打包的过程中,还可以对资源进行处理,比如,压缩图片、将scss转成css、将ES6语法转成ES5语法、将TypeScript转成JavaScript等操作。
关于打包的疑问?grunt/gulp与webpack之间的区别?
grunt/gulp的核心是task。我们可以配置一系列的task,定义好task要处理的事务(例如,ES6、ts转化、图片压缩、scss转成css)之后,让grunt/gulp来依次执行这些task,并让其自动化。所以grunt/gulp也被称为前端自动化任务管理工具
总结:
1.grunt/gulp更加强调的是前端流程的自动化,模块化不是它的核心
2.webpack更加强调模块化开发管理,而文件压缩合并、预处理等功能,是他附带的功能
结论:
1.当我们的项目只需要进行简单的合并、压缩,就使用grunt/gulp即可;
2.如果整个项目使用了模块化管理,而且相互依赖性很强,就需要使用webpack
二、webpack安装
2.1.安装前提:node.js
安装webpack的前提是安装了node.js,Node.js中自带了软件包的管理工具npm。
如果我们已经安装了node.js,那么我们可以通过下面的命令查看自己的node版本:
执行代码:node -v
可以直接在官网下载
网址: 下载 | Node.js 中文网
注意:安装node.js后会默认安装Node和npm
2.1.1.什么是npm?
NPM的全称是Node Package Manager。是一个NodeJS包管理和分发工具,已经成为了非官方的发布Node模块(包)的标准。在一个项目中,当我们使用到一些需要安装的依赖的时候,我们会使用npm来安装依赖包。
由于国内npm的官方镜像的速度较慢,我们推荐使用淘宝镜像来解决这个问题
执行代码:npm install -g cnpm --registry=https://registry.npm.taobao.org
此时,我们就可以使用cnpm来进行操作了
2.2.webpack全局安装
执行代码:npm install webpack -g
2.3.webpak局部安装
为什么要进行局部安装?
通常,我们使用的webpack往往是全局的webpack。但是,这样是不合理的,因为一个项目往往依赖的版本并不是我们全局的那个版本,导致打包出错。所以,一般来说,一个项目都有自己局部的webpack。当我们进行局部安装后,package.json文件中定义的webpack命令使用的就是局部安装的webpack了。
执行代码:npm install webpack@版本号 --save-dev
三、webpack的基本使用
3.1.初始化项目
3.1.1.初始化node
node是我们使用webpack时必须使用的东西,它可以给我们提供一些常用的依赖,我们只需要require引入就可以使用。当我们的项目中需要使用node相关的任何东西时,我们就通过npm对项目进行初始化。
执行代码:npm init
此时,我们只需要一次输入其所需要的信息即可,实际上,除了包名称需要我们自己输入和入口文件(默认为webpack.config.js,后续需要使用,因此需要更改,随便输入即可,我使用的index.js)以外,其余的版本号、描述等,我们直接回车就好。最后,回讯我们需不需要生成package.json文件,其中保存的就是我们项目的信息,我们选择生成即可。
注意:当我们后面使用了新的依赖的时候,我们只需要执行npm install就可以让我们的依赖生效了。
3.1.2.局部webpack
安装项目所需要的局部的webpack
执行代码:npm install webpack@版本号 --save-dev
3.2.webpack的配置
3.2.1.入口和出口的配置:
如果每次使用webpack都需要写入口和出口参数(就是入口所在文档以及要打包到的位置,这里我们用./src/main.js作为入口位置,./dist/bounce.js作为出口),就会非常麻烦,我们可以使用一种简便的办法:可以直接使用webpack来执行
1.我们首先需要创建一个webpack.config.js文件
2.在这个文件中,通过module.exports来导入出入口
entry:入口 output:出口
const path = require('path');
module.exports = {
entry: './src/main.js',//入口
output: {//出口
path: path.resolve(__dirname, 'dist'),//动态获取我们的路径
filename: 'bundle.js'//文件名
},
}
值得注意的是,这里的path需要绝对路径,但是如果我们写死的话,我们有需要每次都重新出入绝对路径,较为麻烦,因此我们可以通过引入path来动态的添加我们的绝对路径 具体情况可以查看webpack.config.js文件。path是我们的node中的依赖包。
3.2.2.配置执行脚本
我们可以在package.json文件的scripts中定义自己的执行脚本
格式:"脚本名": "webpack"
使用方式:npm run 脚本名
package.json文件的scripts中的脚本在执行时的顺序,先去寻找本地(即项目本身)的node_modules/.bin路径中对应的命令来执行,没有找到才会去全局中寻找,当我们使用vue-cli创建项目之后,会自动添加一些常用命令,理解就好。
3.3.开始打包并使用
3.3.1.使用webpack打包
方式一:通过node_modules/.bin/webpack启动webpack来打包
方式二: 使用我们上面配置好的执行脚本
使用方式:npm run 脚本名
3.3.2.使用打包后的文件(了解)
后面会通过plugin来将html也直接打包,这里只用作了解
通过npm run 脚本名打包文件后,我们得到了一个打包文件,但是我们得要如何使用呢?实际上我们只需要在我们的index.html的body中通过script标签来将其引入即可。
<script src="dist/bundle.js"></script>
四、webpack中的loader
4.1.什么是loader?为什么我们要使用loader?
loader是webpack中的一个非常核心的概念。
webpack本身可以帮我们将js代码进行打包处理,但是,一个项目仅仅有基本的js代码处理是完全不够的,我们引入的css、图片,也包括一些高级的,将ES6转成ES5,将TypeScript转成ES5代码,将scss、less转成css,将.jsx、.vue文件转成js文件等都是一个项目可能会用到的东西。对于webpack本身的能力来说,这些转化是不支持的。因此,我们需要给webpack扩展对用的loader也就是说,loader可以让我们webpack的打包功能更全面。
4.2.loader使用过程:
1.通过npm安装需要使用的loader
npm install --save-dev 我们要使用的loader
2.在webpack.config.js中的modules关键字下的rules中进行配置
注意:module和entry、output是同一个层级
当我们确定要使用loader时,我们可以在官方网站查询对应的loader的使用方式,这里只列出几种常用的loader应该在何处使用,具体使用方式就不做赘述。
4.2.1.css-loader(style-loader)
css样式文件
css-loader只负责加载css样式文件,但是将css具体样式嵌入到我们的文档中,还需要style-loader
4.2.2.less-loader(scss、stylus)
less样式文件
less-loader是当我们的项目使用到了less来写样式的时候,我们就需要使用less-loader,同样的,scss、stylus也是一样的
4.2.3.url-loader
小于8kb的图片
url-loader是当我们的使用的图片是小于8kb的时候,我们就可以使用该loader来让我们的图片可以加载
4.2.4.file-loader
大于8kb的图片
file-loader是当我们的使用的图片是大于8kb的时候,我们就可以使用该loader来让我们的图片可以加载
4.2.5.babel-loader!!
用于将ES6转化成ES5文件,来让浏览器可以更好的运行我们项目,因为,部分浏览器不支持ES6的语法。
4.3.图片文件处理
我们发现webpack打包图片的时候会自动生成一个非常长的名字,这是一个32位hash值,目的是防止名字重复。但是,如果我们不进行一定的设置,那么图片数量变多的同时,我们也不能分辨哪个图片是哪个,所以,如果我们可以对webpack打包后的图片名称进行一定的规范,这样在防止 了重名的同时也有助于我们分辨图片。
比如,将所有的图片放在一个文件夹中,跟上图片原来的名称,同时也要防止重复
所以,我们可以在图片的loader配置中user下的options中添加规则:
img:文件要打包到的文件夹
name:获取图片原来的名字,放在该位置
hash:8:为了防止图片名称冲突,依然使用hash,但是我们只保留8位
ext:使用图片原来的扩展名
test: /\.(png|jpg|gif|jpeg)$/,
use: [
{
loader: 'url-loader',
options: {
//当加载的图片,小于limit时,会将图片编译成base64字符串形式
//当加载的图片,大于limit时,会报错,需要使用我们的file-loader进行加载
limit: 13000,
name: 'img/[name].[hash:8].[est]'
},
}
],
但是,我们发现图片并没有显示出来,前面我们提到过,我们的index.html并没有打包到我们的dist文件夹的下面,因此我们在使用打包好的bundle.js文件是直接在index.html文件下引用,但是,我们最终实现的效果肯定是将index.html文件也打包到dist文件夹中。
也就是说,我们此时打包的boundle.js文件中的图片路径是按照dist文件夹下的index所设定的。而按照最终效果而言,图片路径是按照dist文件夹下index的路径编写的,我们在src目录下的index使用,因此图片就找不到了。
所以,我们需要在路径配置相关信息中再添加一个dist/
注意:这个配置在我们使用plugin将html也打包到dist文件夹下的时候,就不需要这个了。
output: {
path: path.resolve(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: 'dist/'//添加的内容
},
五、webpack配置vue
5.1.下载安装我们的vue
注意:vue在我们后面的实际项目运行时中也会使用vue,因此它并不是一个开发时依赖,所以我们使用--save安装,没有-dev
执行代码:npm intall vue --save
5.2.配置vue
5.2.1.为什么要配置vue?
当我们在代码中import引入我们的vue之后,就可以通过new Vue来创建vue实例,并将其挂载到我们的元素上,但是当我们实际运行的时候却发现,我们此时不能直接使用我们的vue,这是因为我们的项目中使用的vue的版本的原因。实际上我们此时使用的runtime-only的版本,它不能很好地对我们的vue的template进行解析。
runtime-only:代码中不可以有任何的template
runtime-compiler:代码中,可以用template,因为有compiler可以用于编译template
而我们挂载的那个元素就是我们创建的vue的template,默认情况下,我们使用的是不能使用template的runtime-only版本,所以,我们需要通过在webpack.config.js配置文件中配置resolve来指定我们所使用的版本 。
注意:resolve和entry、output、module是同一层级
resolve: {
extension: ['.js', '.css', '.vue'],//路径的后缀名,扩展名
//alias:别名
alias: {
'Vue$': 'vue/dist/vue.esm.js'
}
}
5.2.2.vue-loader vue-template-compiler
事实上,我们在使用vue时,习惯于把模板、script、style三者分离开编写,这样不仅结构清晰,维护起来比更翻遍,但是这种特殊的方式也就必然需要一个特殊的处理,因此,我们就需要安装新的loader来让webpack来帮我们进行处理。这个 loader就是我们的vue-loader,具体使用方式请查询官网Loaders | webpack 中文文档
5.3.起别名
在我们的开发中,我们可以通过起别名的方式来让我们代码中的路径看起来更为直观,编写起来也更简单
注意:
1.我们默认情况下,对于src已经起了一个别名@
2.configureWebpack和entry、output、module等是同一层级。
1.普通的起别名的方式
configureWebpack: {
resolve: {
alias: {
'components': '@/components',
'pages': '@/pages',
}
}
}
2.利用webpack4的webpack-chain进行别名的配置
chainWebpack: (config) => {
config.resolve.alias
.set('@$', resolve('src'))
.set('components', resolve('src/components'))
}
前者配置方式较为简单,但是后者可以实现更为细粒的配置效果。
六、plugin插件
6.1.plugin是什么?
plugin:插件
所谓的插件,就是对某个现有的架构进行扩展,让其功能更为完善。
6.2.loader和plugin的区别
loader实际上是转换某些类型的模块
plugin则是对webpack现有的功能进行扩展
就像webpack的打包功能,它本身就有将js转化的能力,只是对js中引用的某些其他类型的转化不支持,而loader是给webpack提供了转化,是完善他的js转化打包功能。但是webpack本身不打包html,我们可以通过插件让webpack也可以打包html。
6.3.plugin的使用
步骤一:通过npm安装需要使用的plugins(某些webpack已经内置的插件不需要安装)
步骤二:在webpack.config.js中的plugins中配置插件。
注意:plugins和resolve、entry、output、module是同一层级
具体的使用方式跟loader类似,当我们想要使用plugin时,我们需要从webpack官网查看其具体用法。这里我们仅给出一些常见的plugin的使用情况说明,具体使用方式并不意义赘述
6.3.1.BannerPlugin
添加版权说明
为打包的文件添加版权,安装并配置此插件后,我们打包的js文件的最上面就会有我们设定好的版权说明。类似“最终解释权归***所有”
6.3.2.HtmlWebpackPlugin
打包HTML到dist
在真实发布项目时,发布的是dist文件夹中的内容,因此,我们需要把index.html文件也一并打包到我们的dist文件夹中。这个时候就可以使用HtmlWebpackPlugin插件了。
该插件可以帮我们完成两件事情:
1.自动生成一个index.html文件(我们也可以指定模板来生成)
2.将打包的js文件,自动通过script标签插入到body中
6.3.3.uglifyjs-webpack-plugin(丑化代码)
丑化代码
在项目发布之前,我们需要对js等文件进行压缩处理,这会让我们项目整体变的更小,而且也更为安全,毕竟丑化后的代码谁又能看的懂呢?......
七、搭建本地服务器
webpack提供给我们一个可选的本地开发服务器,这个本地服务器基于node.js搭建,内部使用express框架,可以实现我们想要的让浏览器自动刷新显示我们修改后的结果。但是,我们初始的webpack是没有这项功能的,他还需要安装才能使用。
7.1.通过npm安装
执行代码 :npm install --save-dev webpack-dev-server
7.2.添加配置
类似vue的配置,我们的本地服务器的配置,是在webpack.config.js中的devserver中配置插件。
注意:devserver和plugins、resolve、entry、output、module是同一层级
7.2.1.devserver的属性
devserver也是作为webpack中的一个选项,选项本身可以设置如下属性:
contentBase:为哪一个文件夹提供本地服务,默认是根文件夹,我们这里要填写./dist,这是因为我们最后打包的文件夹就是我们的dist
port:端口号
inline:页面实时刷新//true或false
historyApiFallback:在SPA页面中,依赖HTML5的history模式(路由中使用)
devServer: {
contentBase: './dist',
inliner: true,
},