1.什么是webpack?
WebPack也叫做模块打包机。
作用:分析你的项目结构,找到JavaScript模块以及其它的一些浏览器
不能直接运行的拓展语言(Scss,TypeScript等),并将其转换和打包
为合适的格式供浏览器使用。
在 Webpack 里一切文件皆模块,通过 Loader 转换文件,通过 Plugin 注
入钩子,最后输出由多个模块组合成的文件。
2. 为什么要用webpack?
-
Webpack与Gulp/Grunt区别
Gulp/Grunt是一种能够优化前端的开发流程的工具((任务流工具),而WebPack是
一种模块化的解决方案(模块打包工具);a. Gulp/Grunt和webpack的工作方式有较大的区别:
1)Grunt和Gulp的工作方式是:在一个配置文件中,指明对某些文件进行类似
编译,组合,压缩等任务的具体步骤,工具之后可以自动替你完成这些任务。2): Webpack的工作方式是:把你的项目当做一个整体,通过一个给定的主文件(如:index.js),Webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理它们,最后打包为一个(或多个)浏览器可识别的JavaScript文件
b. 被grunt和gulp对代码的处理,只是局部变量名被替换简化,整体并没有发生改变,还是自己的代码,而webpack则进行了更彻底的打包处理,更加偏向对模块语法规则进行转换。主要任务是突破浏览器的鸿沟,将原本浏览器不能识别的规范和各种各样的静态文件进行分析,压缩,合并,打包,最后生成浏览器支持的代码,因此,webapck打包过后的代码已经不是你写的代码了;
c. Gulp/Grunt集成度不高,要写很多配置后才可以用,无法做到开箱即用;
而webpack专注于处理模块化的项目,能做到开箱即用一步到位,使用场景不限于web开发。但是webpack只能用于采用模块化开发的项目。2)Grunt vs Gulp
Grunt的出现早于Gulp,他们本质上都是通过JavaScript语法实现了shell script命令的一些功能。
a. 书写方式
grunt 运用配置的思想来写打包脚本,一切皆配置,所以 会出现比较多的配置项,诸如option,src,dest等等。而且不同的 插件可能会有自己扩展字段,导致认知成本的提高,运用的时候 要搞懂各种插件的配置规则。 gulp 是用代码方式来写打包脚本,并且代码采用流式的写法,只抽 象出了gulp.src, gulp.pipe, gulp.dest, gulp.watch 接口,运用相当简单 。经尝试,使用gulp的代码量能比grunt少一半左右。
b. 任务划分
grunt 中每个任务对应一个最外层配置的key, 大任务可以包含小任务, 以一种树形结构存在。 gulp 中没有子任务的概念。
c. 运行效率
grunt 采用串行的方式执行任务 gulp 基于并行执行任务的思想
3. loaders
webpack 只能理解 JavaScript 和 JSON 文件。loader 让 webpack 能够去处理其他类型的文件,
并将它们转换为有效 模块,以供应用程序使用,以及被添加到依赖图中。
Loaders需要单独安装并且需要在webpack.config.js中的modules关键字下进行配置,Loaders
的配置包括以下几方面:
test:一个用以匹配loaders所处理文件的拓展名的正则表达式(必须)
loader:loader的名称(必须)
include/exclude:手动添加必须处理的文件(文件夹)或屏蔽不需要处理的文件
(文件夹)(可选);
query:为loaders提供额外的设置选项(可选)
4.webpack的基本使用
要使用webpack首先需要安装好node的环境
-
首先全局安装webpack
npm install -g webpack@3.6.0
webpack1.0+的版本和2.0+、3.0+的版本时不兼容的,
-
创建一个项目文件夹,然后执行npm init 指令,它会弹出很多问答,如项目名称、作者、密码之类的,一般全部回车即可,这个指令是npm的标准配置文件,能够生成package.json文件,记录这个项目相关的配置和安装过的依赖。
npm init
-
cd到项目文件夹下把webpack安装到你的项目目录里面
npm install --save-dev webpack@3.6.0
-
回到之前的空文件夹,并在里面创建两个文件夹,app文件夹和public文件夹,app文件夹用来存放原始数据和我们将写的JavaScript模块,public文件夹用来存放之后供浏览器读取的文件(包括使用webpack打包生成的js文件以及一个index.html文件)。接下来我们再创建三个文件:
index.html --放在public文件夹中;
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Webpack Sample Project</title> </head> <body> <div id='root'> </div> <script src="bundle.js"></script> </body> </html>
Greeter.js-- 放在app文件夹中
module.exports = function() { var greet = document.createElement('div'); greet.textContent = "Hi there djgdghodghdo greetings!"; return greet; }; ```
main.js-- 放在app文件夹中
const greeter = require('./Greeter.js');
document.querySelector("#root").appendChild(greeter())
5.至此,webpack打包文件之前需要做的准备都已经好了,接下来就是打包文件了,打包文件有两种方式,一种是手动打包,一种是通过配置文件打包;
1)手动打包文件的操作方法如下:
# {extry file}出填写入口文件的路径,本文中就是上述main.js的路径, # {destination for bundled file}处填写打包文件的存放路径 # 填写路径的时候不用添加{} webpack {entry file} {destination for bundled file}
webpack app/main.js public/bundle.js
如果打包成功会有相应的提示,并生成对应的bundle.js打包后的文件。
- 通过配置文件打包文件:
首先在项目的根目录下创建一个webpack.config.js文件,文件的配置信息如下:
//“__dirname”是node.js中的一个全局变量,它指向当前执行脚本所在的目录。
module.exports = {
devtool: 'eval-source-map', //生成source-maps帮助我们找到出错的地方,eval-source-map能构建出完整的source-maps,速度快,适合开发阶段,生产阶段不适合
entry: __dirname + "/app/main.js", //唯一的入口文件
output: {
path: __dirname + "/public", //打包后的文件存放的地方
filename: "bundle.js" //打包的文件名
}
}
配置此文件之后可以直接在命令行输入"webpack"指令就可以直接打包文件了。
注意:如果你觉得输入webpack很麻烦那么你可以通过在package.json文件中配置:
{
"name": "webpack-sample-project",
"version": "1.0.0",
"description": "Sample webpack project",
"scripts": {
"start": "webpack" // 修改的是这里,JSON文件不支持注释,引用时请清除
},
"author": "zhang",
"license": "ISC",
"devDependencies": {
"webpack": "3.10.0"
}
}
配置完后则直接在在命令行输入npm start
打包成功的话你会在public目录下看到打包后的文件bundle.js
** 查看打包结果有两种方式,一是在命令行,二是在浏览器查看 **
a. 命令行查看,你可以在命令行窗口输入以下指令:(一般不使用)
node public/bundle.js
命令行会打印出运行结果。(你的文件里面有document的相关操作,如,创建节点等 命令行会报“documnet no defined”的错误,js文件中使用console则不会,能正常打印出结果)
b. 这时webpack打包的文件是没有部署服务的,如果你在浏览器输入localhost/public/index.html是不会有结果的,应该要在浏览器输入:
file:///D:/demoproject/public/index.html
如果文件打包没问题的话就会在浏览器中输出Greeter.js中的文本内容
思考:如果我一定要用localhost在浏览器访问项目的index.html呢?
打包过几遍之后你会发现,以上配置有一个很不友好的地方就是,如果你修改文件中的某一个布局或者样式,你要看到修改的效果是需要再次打包的,打包成功之后才能看到修改的内容;
那么有什么方法能让我们能用localhost就可以在浏览器访问到项目的页面,对于页面的修改能够动态刷新呢?
webpack-dev-server能很好的帮我们解决这个需求。
-
什么是webpack-dev-server?
webpack-dev-server是webpack官方提供的一个小型Express的http服务器。相当于webpack+apache,启动一个web服务并实时更新修改。
它的作用主要是用来服务资源文件(默认在当前目录下,可通过content-base指定)。此外这个Http服务器和client使用了websocket通讯协议,原始文件作出改动后,webpack-dev-server会实时的编译,但是最后的编译的文件并没有输出到目标文件夹,而是保存在内存中。
-
webpack-dev-server的使用
webpack和webpack-dev-server的搭配使用是有版本限制的,一般我们要遵循向下兼容的原则,尽量使用同一版本的webpack和webpack-dev-server,或者高版本的webpack和低版本的webpack-dev-server;
本文使用webpack3.6.0和webpack-dev-server1.15.0;
1)全局安装webpack-dev-server
npm install webpack-dev-server@1.15.0 -g
2)在项目中安装webpack-dev-server
npm install --save-dev webpack-dev-server@1.15.0
- 修改配置webpack.dev.config.js文件
const path = require('path') module.exports = { devtool: 'eval-source-map', //生成source-maps帮助我们找到出错的地方,eval-source-map能构建出完整的source-maps,速度快,适合开发阶段,生产阶段不适合 entry: __dirname + "/app/main.js", //唯一的入口文件 output: { path: __dirname + "/public", //打包后的文件存放的地方 filename: "bundle.js" //打包的文件名 }, devServer: { port: 8080, //端口 contentBase: path.join(__dirname, './public'), //本地服务器所加载的页面所在的目录 historyApiFallback: true, //如果设置为true,所有的跳转将指向index.html host: '127.0.0.1', inline: true //实时刷新 } }
- 执行命令开启web服务
webpack-dev-server --config webpack.dev.config.js --color --progress
- 访问网址: http://127.0.0.1:8080/
注意:如果要简化以上命令的话可以配置package.json文件
{ "name": "demoproject", "version": "1.0.0", "description": "", "main": "index.js", "scripts": { "test": "echo \"Error: no test specified\" && exit 1", "build": "webpack --config webpack.dev.config.js", "start": "webpack-dev-server --config webpack.dev.config.js --color --progress" }, "author": "", "license": "ISC", "devDependencies": { "webpack": "^3.6.0", "webpack-dev-server": "^1.15.0" } }
配置完后,运行命令可以改为 npm start