webpack中文文档:==传送门==
webpack英文文档:==传送门==
1、什么是webpack:
webpack可以看做是模块打包机:它做的事情是,分析你的项目结构,找到JavaScript模块以及其它的一些浏览器不能直接运行的拓展语言(Scss,TypeScript等),并将其打包为合适的格式以供浏览器使用。
2、为什么要使用webpack:
如今的很多网页其实可以看做是功能丰富的应用,它们拥有着复杂的JavaScript代码和一大堆依赖包。为了简化开发的复杂度,前端社区涌现出了很多好的实践方法
a:模块化,让我们可以把复杂的程序细化为小的文件;
b:类似于TypeScript这种在JavaScript基础上拓展的开发语言:使我们能够实现目前版本的JavaScript不能直接使用的特性,并且之后还能能装换为JavaScript文件使浏览器可以识别;
c:scss,less等CSS预处理器
.........
这些改进确实大大的提高了我们的开发效率,但是利用它们开发的文件往往需要进行额外的处理才能让浏览器识别,而手动处理又是非常繁琐的,这就为WebPack类的工具的出现提供了需求。
3、webpack和Grunt以及Gulp相比有什么特性:
其实Webpack和另外两个并没有太多的可比性,Gulp/Grunt是一种能够优化前端的开发流程的工具,而WebPack是一种模块化的解决方案,不过Webpack的优点使得Webpack可以替代Gulp/Grunt类的工具。
Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,这个工具之后可以自动替你完成这些任务。
Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个浏览器可识别的JavaScript文件。
优点:模块化
在webpack看来一切都是模块!这就是它不可不说的优点,包括你的JavaScript代码,也包括CSS和fonts以及图片等等等,只有通过合适的loaders,它们都可以被当做模块被处理。
接下来开始实际操作:
1、使用命令行全局下载webpack:
npm i webpack@3.6.0 -g
这里不推荐使用npm i webpack -g 因为不添加版本下载,直接默认最新版本的webpack,会出现版本过高,无法执行相关指令,指令不熟悉的问题,所以高版本切换到低版本。
2、创建项目文件(这里所使用HBuilderX进行操作):
- 首先创建项目文件夹;
- 文件夹下创建两个名为src/dist的子文件夹;
- src文件夹下创建一个html文件和一个js文件,index.html&&main.js
3、所要渲染的html代码:
<body>
<ul>
<li>1</li>
<li>2</li>
<li>3</li>
<li>4</li>
<li>5</li>
<li>6</li>
<li>7</li>
<li>8</li>
<li>9</li>
</ul>
</body>
4、改变样式(基数行的li为一种颜色,偶数行的li为一种颜色):
这里使用jquery实现样式的添加(项目使用npm安装juqery依赖包);
- 首先在HBuilder页面Alt+C打开终端(无终端的会提示下载);
- 其次在终端命令行内使用指令:npm init -y
- 然后继续在终端命令行内使用指令:npm i jquery -S
import $ from 'jquery' //ES6中导入其它模块的语法
$(function(){
$('li:odd').css('backgroundColor','pink') //选择奇数行
$('li:even').css('backgroundColor',function(){ //选择偶数行
return '#' + 'D49BCD'
})
})
在渲染层index.html内引入main.js(所有js指令和css样式都定义在此文件内,避免二次请求)
<script src="main.js"></script>
5、运行代码:
发现背景颜色并没有添加成功,检查,报错提示信息:Uncaught SyntaxError: Unexpected identifier(未捕获SyntaxError:意外标识符)
是因为代码内使用了ES6语法,而浏览器对ES6的识别度并不好,所以并不能正常运行main.js内的代码;
解决办法:在编辑器终端使用命令
webpack .\src\main.js .\dist\bundle.js
成功后如下图
注意: .\src\main.js是我们需要打包的js文件,.\dist\bundle.js是我们要输出的文件(bundle是我们定义创建的输出文件名,可为其它名字),操作此命令成功后,dist文件下会生成一个bundle.js文件,而这个文件通过webpack的打包,所生成的代码浏览器可识别;
既然此时main.js无法被浏览器所识别,且生成的bundle.js可被浏览器所识别,所以index.html文件内直接引入bundle.js即可:
<script src="../dist/bundle.js"></script>
总结webpack可以做什么事情:
- 能够处理JS文件的相互依赖问题
- 能够处理JS的兼容问题,把高级的浏览器不能识别的语法,转化为低级的浏览器能识别的语法
6、修改奇数项的li的backgroundColor的颜色:
如果想让奇数项li的颜色为红色,那么我们需要在main.js内把"pink"修改为"red",那么问题来了,修改以后,只是main.js文件被修改了,而页面渲染的是bundle.js的内容,这里又需要重新打包,如果这样每次有修改都要重新打包(是不是已经忘记打包的方法了webpack .\src\main.js .\dist\bundle.js),那么我们的时间都会浪费在这样的重复操作上了;
So优化1来了:
根目录下新建名为webpack.config的js文件,并且删除掉之前dist目录下生成的bundle.js文件
const path = require('path') //定义路径操作的path模块
//这个配置文件,其实就是一个js文件,通过Node中的模块化操作,向外暴露了一个配置对象
module.exports = {
entry:path.join(__dirname,'./src/main.js'), //入口,表明webpack要打包的文件","号不要忘记,这里是双下滑线!!!
output:{ //输出文件相关的配置
path:path.join(__dirname,'./dist'), //指定打包好的文件输出到哪个目录中去
filename:'bundle.js' //指定输出文件名称
}
}
此时当我们修改了main.js文件后,只需在终端命令行输入:webpack,回车即可打包新的bundle.js文件;
当我们在终端控制台,直接输入命令“webpack”执行的时候,“webpack”做了哪些工作:
- 首先,webpack发现我们并没有给它指定入口和出口;
- 然后,webpack会去项目的根目录下查找"webpack.config.js"的配置文件;
- 紧接着,当找到配置文件后,回去解析并执行这个配置文件;
- 配置文件中我们预先配置好了入口和出口,so,webpack就开始打包构建。
即使这样,也仅仅是做了简化,并没有从根源上解决掉重复打包的操作,一个项目下来总要修改很多次,比如想要修改一个按钮的长度,修改后想要看其效果,这样也需要打包一次,毫无疑问,即使再有耐心的光头,哦,不,再有耐心的程序猿,也会苦恼想砸键盘,说到底,你就是太懒,好吧,好吧,满足你!
终极优化2:
使用webpack-dev-server这个工具来实现自动打包、编译。
而使用webpack-dev-server这个工具又要建立在webpack这个工具上,打开package.json发现里面并没有webpack的相关版本信息(没下载怎么能查到,说了句废话):
- 首先将根目录下的node_modules文件删除掉;
- 然后在终端命令行内执行命令(不建议使用4.0以上的版本!!!):npm i webpack@3.6.0 -g
- 紧接着执行命令(这里推荐使用2.9.3版本!!!):npm i webpack-dev-server@2.9.3 -D
- 在package.json文件内的scripts内配置:"dev":"webpack-dev-server"
此时每当我们修改了main.js内的信息,保存文件以后,webpack-dev-server都会自动打包编译,需要注意的是编译信息内:Project is running at http://loacalhost:8080/;
浏览器打开http://loacalhost:8080/,会发现显示的是我们的根目录,我们的index.html在src文件夹下,所以点击打开src文件夹,index.html就直接解析编译渲染出来了。
此时我们还要考虑一个问题,那就是index.js文件引入的bundle.js文件跟webpack解析生成的bundle.js文件是否为同一个文件,我们可以将dist文件夹下的bundle.js文件删除,然后打开浏览器http://localhost:8080/bundle.js会发现浏览器内会渲染出一个bundle.js文件,所以此bundle文件跟我们刚刚删除的文件并不是同一个文件,这里我们直接将index.html内引入的dist文件夹下bundle.js文件替换为根目录下的bundle.js即可:
<script src="/bundle.js"></script>
巴拉巴拉: