非常感谢胖哥的博客和掘金小册的技术分享,希望大家去下面的链接去查看原文,他们写的非常好,都是多个项目经验的总结!!!感谢
本篇文章是 技术胖 博客学习笔记整理,供后续查阅使用
在如今大前端的时代,webpack可以说是肩负重任,在项目中不可或缺!(严肃脸)
学习webpack您需要的设备:
1、电脑(能上网)
2、编辑器
3、一杯星巴克
什么是webpack:
webpack可以看做是模块打包机,它做的事情是,分析你的项目结构,找到js模块以及其他的一些浏览器不能运行的拓展语言(sass、less、typescript),并将其转换和打包为合适的格式供浏览器使用。在3.0出现后,webpack还肩负起了优化项目的责任
从上面这段话中抽取出来三个重点:
1、打包:可以把JavaScript文件打包成一个文件,减少服务器压力和下载带宽
2、转换:把拓展语言转换成普通的JavaScript,让浏览器顺利运行
3、优化:前端变得越来越复杂后,性能也会遇到问题,而webpack也开始肩负起了优化和提升性能的责任
我们可以通过下图了解webpack的作用
webpack安装webpack
默认你的电脑已经装过了node(不会的,出门右拐找google)
新建一个webpack学习目录 webpackpro
安装命令区别:
1、npm i webpack -g 全局安装
2、npm i webpack --save 保存安装包信息到package.json中
3、 npm i webpack --save-dev 在开发环境中使用这个包 development
4、npm i webpack -D 是第三个命令的缩写
注意!注意!注意!:::这个教程里用的是3.0版本,但是最新版是4.0,不要装错了
使用 npm i webpack@3.11.0 -D 命令安装3.11.0版本
文章最后会有怎么安装模块特殊版本的说明
开发环境和生产环境
开发环境:在开发时需要的环境,这里指在开发时需要依赖的包
生产环境:程序开发完成,开始运行后的环境,这里指要使项目运行所需要的依赖包
如果安装失败(出现了报错信息),一般有三种可能:
1、node版本过低,升级版本
2、网络问题,用cnpm(淘宝的npm实时更新镜像)
3、权限问题,在Liux和Mac上是需要安装权限的,如果是win系统,使用管理员方式安装
全局安装时可以的,但是webpack官方不推荐,这回将你项目中的webpack锁定到指定版本,并且在使用不同的webpack版本的项目中,可能会导致构建失败
初始化项目
npm init
一路回车到底
npm i webpack --save-dev
查看webpack版本,也是检查webpack是否安装好的一种方法
webpack -v
建立项目结构
在webpackpro目录下,新建src和dist文件夹,在src下新建entry.js作为入口文件,在dist文件下新建一个index.html文件(暂时的,以后会自动生成),写入以下内容
entry.js此时的项目目录应为
打包前项目目录此时在webpackpro目录下运行命令
执行效果webpack src/entry.js dist/bundle.js
再来看下项目目录,自动生成了bundle.js文件
打包后项目目录这时可以在浏览器中查看index.html的运行效果
配置文件:入口和出口
配置文件 webpack.config.js
webpack.config.js就是webpack的配置文件,需要自己在项目根目录下创建
webpack.config.jsentry
多入口、多出口的配置
很简单,只需要多加个入口entry、把出口改成活的即可
多入口、多出口配置服务和热更新
安装webpack-dev-server
npm i webpack-dev-server -D
webpack-dev-server主要提供两个功能
1、伪静态文件提供服务
2、自动刷新和热替换(HMR)
配置devServer
devServercontnetBase:配置服务器基本运行路径,用于找到程序打包地址
host:服务运行地址,建议使用本机IP,这里为了方便,所以用localhsot
compress:服务器端压缩选型,一般设置为开启
port:服务运行端口,不建议使用80,很容易被占用
最后在package.json中配置启动命令
"server": "webpack-dev-server"
这里东西比较多,打算新开一个webpack-dev-server文章讲解
css文件打包
简单介绍loaders
loaders是webpack最重要的功能之一,通过不同的loader对不同格式的文件进行特定的处理
配置项:
test:用于匹配处理文件的扩展名的表达式,这个选项是必须进行配置的
use:loader名称,就是你要使用的模块名称,这个选项也必须进行配置,否则报错
include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件(可选)
query:为loaders提供额外的设置选项(可选)
安装loader
在src文件夹下建立css/index.css,并输入以下内容
body{ background-color: red; color: white;}
在entry.js中引入
import css from './css/index.css';
打包css要用到两个loader:
style-loader:处理css文件中的url()
css-loader:将css插入到页面的style标签
npm i style-loader css-loader -D
loaders配置
这三种写法效果是相同的
压缩js代码
uglifyjs-webpack-plugin是js压缩插件,在webpack中默认已经集成,不需要安装
引入
const uglify = require('uglifyjs-webpack-plugin');
在plugins配置里new一个uglify对象就可以了:
压缩js此时在页面中查看js文件就是压缩过的
html文件的发布
文件结构的变更说明:把dist下的index.html文件移动到src下,并删除引入的js文件
安装html-webpack-plugin插件
npm i html-webpack-plugin -D
在webpack.config.js中引入
const htmlPlugin= require('html-webpack-plugin');
配置
配置html-webpack-pluginminify:对html文件进行压缩,removeAttrubuteQuotes是去掉属性的双引号
hash:避免开发中js有缓存效果
template:要打包的html模板路径和文件名称
此时,在命令行中运行webpack后,注意目录结构中自动生成了index.html和bundle.js文件
css中的图片处理
首先在index.html中添加一个标签比如:
图片标签 img样式安装loaders
npm i file-loader url-loader -D
file-loader:解决引用路径的问题,拿background样式用url引入背景图来说,我们都知道,webpack最终会将各个模块打包成一个文件,因此我们样式中的url路径是相对入口html页面的,而不是相对于原始css文件所在的路径的。这就会导致图片引入失败。这个问题是用file-loader解决的,file-loader可以解析项目中的url引入(不仅限于css),根据我们的配置,将图片拷贝到相应的路径,再根据我们的配置,修改打包后文件引用路径,使之指向正确的文件。
url-loader:如果图片较多,会发很多http请求,会降低页面性能。这个问题可以通过url-loader解决。url-loader会将引入的图片编码,生成dataURl。相当于把图片数据翻译成一串字符。再把这串字符打包到文件中,最终只需要引入这个文件就能访问图片了。当然,如果图片较大,编码会消耗性能。因此url-loader提供了一个limit参数,小于limit字节的文件会被转为DataURl,大于limit的还会使用file-loader进行copy。
在配置文件中引入
limit:是把小于500000B的文件达成base64的格式,写入js
css分离与图片路径处理
这里课程两个目的:
1、把css从JavaScript中分离出来
2、处理分离出来的css中图片路径不对问题
css分离:extract-text-webpack-plugin
安装 extract-text-webpack-plugin
npm install --save-dev extract-text-webpack-plugin
引入
const extractTextPlugin = require("extract-text-webpack-plugin");
new extractTextPlugin("/css/index.css")
/css/index.css 是指分离后的路径位置
修改loader
处理HTML中的图片 html-withimg-loader
把图片放到指定的文件夹下
安装命令
npm i html-withimg-loader -D
配置loader
Less、Sass文件打包和分离
less:npm i less less-loader -D
sass: npm i sass-loader node-sass -D
和上面的写法一样
自动处理css3属性前缀
通过postcss-loader给css3属性自动添加前缀
npm i postcss-loader autoprefixer -D
先在项目根目录下新建postcss.config.js文件,写入以下内容
postcss.config.js编写loader
消除未使用的css
如果在项目中使用想bootstrap这样的框架会有很多css是用不上的,或者项目开发周期久了就会有很多无用的css样式造成css冗杂
PurifyCSS
使用PurifyCSS可以大大减少css冗杂,比如我们经常使用的bootstrap104kb就可以减少到只有35kb
安装PurifyCSS-webpack
npm i purifycss-webpack purify-css -D
在webpack.config.js头部引入purifycss-webpack
const PurifyCSSPlugin = require('purifycss-webpack');
引入glob
因为我们需要同步检查html模板,所以我们需要引入node的glob对象使用
在webpack.config.js头部引入glob
const glob = require('glob');
这里配置了一个paths,主要是找html模板,purifycss根据这个配置会遍历你的文件,查找哪些css被使用了
注意:使用这个插件必须配合extract-text-webpack-plugin
这时在css/index.css中加入一些多余css样式,重新运行webpack,就能看到效果
支持ES6语法
Babel:是一个编译JavaScript的平台,它可以做到
1、使用ES6、ES7。。。新语法,及时这些标准目前并未被当前的浏览器支持
2、使用基于JavaScript扩展的语言,比如React的JSX
Babel的安装和配置
Babel其实是几个模块化的包,其核心功能位于称为babel-core的npm包中,webpack可以把其不同的包整合在一起使用,对于每一个你需要的功能或拓展,你都需要安装单独的包(用得最多的是解析ES6的babel-preset-es2015包和解析JSX的babel-preset-react包)
安装loader
cnpm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
配置babel
.babelrc配置
虽然Babel可以直接在webpack.config.js中进行配置,但是考虑到babel具有非常多的配置选项,如果写在webpack.config.js中不易阅读,所以单独写在.babelrc文件中
{ "presets":["react","es2015"] }
webpack.config.js里loader的配置
ENV
现在比较流行配置env
安装env
npm install --save-dev babel-preset-env
修改.babelrc里的配置文件,只要把es2015换成env就可以了
{ "presets":["react","env"] }
打包后调试
(这节都是理论的东西,直接copy来)
由于打包后html、js、css都压缩了,给调试带来了麻烦,webpack支持Source Maps来方便调试
四种选项
在配置devtool时,webpack给我们提供了四种选项。
source-map:在一个单独文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包速度;
cheap-module-source-map:在一个单独的文件中产生一个不带列映射的map,不带列映射提高了打包速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便。
eval-source-map:使用eval打包源文件模块,在同一个文件中生产干净的完整版的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。在开发阶段这是一个非常好的选项,在生产阶段则一定要不开启这个选项。
cheap-module-eval-source-map:这是在打包文件时最快的生产source map的方法,生产的 Source map 会和打包后的JavaScript文件同行显示,没有影射列,和eval-source-map选项具有相似的缺点。
四种打包模式,有上到下打包速度越来越快,不过同时也具有越来越多的负面作用,较快的打包速度的后果就是对执行和调试有一定的影响。
个人意见是,如果大型项目可以使用source-map,如果是中小型项目使用eval-source-map就完全可以应对,需要强调说明的是,source map只适用于开发阶段,上线前记得修改这些调试设置。
简单的配置:
module.exports = {
devtool: 'eval-source-map',
entry: __dirname + "/app/main.js",
output: {
path: __dirname + "/public",
filename: "bundle.js"
}
}
总结:调试在开发中也是必不可少的,但是一定要记得在上线前一定要修改webpack配置,在打出上线包
下一篇文章总结胖哥博客里的实战技巧
安装模块特殊版本
npm install --save 模块名称(例如react-native-scrollable-tab-view)@版本号(例如0.5.3)
有些模块不指定版本号会出现一些诡异的bug,比如上述的react-native-scrollable-tab-view,我在安装时没指定版本号,默认0.8.0,结果报错,改了半天后索性删除这个模块,重新指定0.5.3版本的安装.
另说明:查看package.json中已安装的库的时候,会发现他们的版本号之前都会加一个符号,有的是插入符号(^),有的是波浪符号(~),那么他们到底有什么区别呢?
比如
~1.15.2 := >=1.15.2 <1.16.0
^3.3.4 := >=3.3.4 <4.0.0
波浪符号(~):他会更新到当前minor version(也就是中间的那位数字)中最新的版本。放到我们的例子中就是:body-parser:~1.15.2,这个库会去匹配更新到1.15.x的最新版本,如果出了一个新的版本为1.16.0,则不会自动升级。波浪符号是曾经npm安装时候的默认符号,现在已经变为了插入符号。
插入符号(^):这个符号就显得非常的灵活了,他将会把当前库的版本更新到当前major version(也就是第一位数字)中最新的版本。放到我们的例子中就是:bluebird:^3.3.4,这个库会去匹配3.x.x中最新的版本,但是他不会自动更新到4.0.0。
package.json 版本号说明
1.版本号基本格式
主号.次号.修补号
2.版本号规则
1)version 指定版本号
"vue-clipboard2": "0.0.8"//指定所依赖的该组件必须是 0.0.8 版本的
2)>version 大于该版本号
"vue-clipboard2": ">0.0.8"//指定所依赖的该组件必须是大于 0.0.8 版本的
3)>=version 大于等于该版本号
"vue-clipboard2": ">=0.0.8"//指定所依赖的该组件必须是 大于或等于0.0.8 版本的
4)<version小于该版本号
"vue-clipboard2": "<0.0.8"//指定所依赖的该组件必须是小于 0.0.8 版本的
5)<=version 小于等于该版本号
"vue-clipboard2": "<=0.0.8"//指定所依赖的该组件必须是小于等于 0.0.8 版本的
6)~version 右侧任意
"vue-clipboard2": "~0.2.1"//该组件版本号 要>=0.2.1,并修补号为 >=1 的任意值
"vue-clipboard2": "~0.2"//该组件版本号 要>=0.2,并修补号为 >=0 的任意值
"vue-clipboard2": "~1"//该组件版本号 要>=1.0.0,次版本号任意,并修补号任意
7)^version 非0右侧任意 从左向右,第一个非0号的右侧任意
"vue-clipboard2": "^0.1.2"//该组件版本号 要>=0.1.2 主版本号为0固定,次版本号为 1 固定,并修补号 >=2 任意值
"vue-clipboard2": "^1.1.2"//该组件版本号 要>=1.1.2 主版本号为1固定,次版本号为 >=1任意值,并修补号为任意值,但次版本号为1时,修补号要>=2,即要满足总版本号>=1.1.2
"vue-clipboard2": "^0.1"//该组件版本号 要>=0.1 缺少的版本号位位置为任意值
8)x-version x位置任意
"vue-clipboard2": "0.1.x"//x位置任意
9)“”|| * version 表示版本任意
"vue-clipboard2": ""//版本任意
"vue-clipboard2": "*"//版本任意
10)version1-version2 表示版本区间范围 包含首尾版本号
"vue-clipboard2": "1.1.1-1.2.9"//版本要求 1.1.1<=版本号<=1.2.9
11)version1||version2||...version 表示或,或version1或version2,支持多个
"vue-clipboard2": "1.1.1-1.2.9 || >=3.5.0 || ^0.1.2"//版本要求满足其一即可
网友评论