Webpack的工作是:分析你的项目结构,找到javascript模块以及其他的一些浏览器不能直接运行的拓展语言,比如less,Typescript等,并将其打包为合适的格式供浏览器使用。
与Grunt和Gulp比较
Gulp和Grunt是一种能够优化前端的开发流程的工具,而Webpack是一种模块化的解决方案,不过Webpack的优点使得webpack可以替代gulp和grunt类的工具。
Grunt和Gulp的工作方式:
在一个配置文件中,指明对某些文件进行类似编译,组合,压缩等任务的具体步骤,这个工具之后可以自动替你完整这些任务。
webpack的工作方式:
把项目当做一个整体,通过一个给定的主文件,比如index.js,webpack将从这个文件开始找到你的项目的所有依赖文件,使用loaders处理他们,最后打包为一个浏览器可以识别的js文件。
webpack的处理速度更块更方便,能打包更多不同类型的文件。
安装webpack
使用npm安装
npm install -g webpack //全局安装
npm install --save-dev webpack //安装到项目目录
用webpack打包的基本语句
webpack {入口文件} {存放bundle.js文件的地方}
比如目录结构:
打包语句为:
webpack app/main.js public/bundle.js
如果webpack非全局安装,则在webpack前面需加上路径,如:node_modules/.bin/webpack
通过命令行webpack可以实现很多比较高级的功能,但不太方便且易出错,因此最好的是定义一个配置文件,这个配置文件也是一个简单的JS模块,可以把所有的与构建相关的信息放在里面。
在根目录创建一个文件叫 webpack.config.js,在里面进行配置:
module.exports = {
entry: __dirname+"/app/main.js",//入口文件
output: {
path:__dirname+"/public",//打包后文件存放的地址
filename:"bundle.js" //打包后输出文件的文件名
}
}
保存这个文件后,在终端运行 webpack 。这样就可以完成打包了。
更简洁的打包方法:
为了避免命令行输入错误,对package.json进行设置后,可以直接通过npm start来运行
package.jsaon 设置如下:
{
"name":"webpack-test",
"version":"1.0.0",
"description":"webpack test",
"script":{
"start":"webpack" //把npm的start命令指向webpack命令
},
"author":"a",
"license":"ISC",
"devDependencies":{
"webpack":"^2.5.1"
}
}
在修改package.json文件时,注意要用双引号,不然会出错。
webpack更多功能
生成Source Maps(使调试更容易)
通过配置后,webpack在打包时可以生成source maps,为我们提供了一种对应编译文件和源文件的方法,使得编译后的代码可读性更高,也更容易调试。
在webpack的配置文件中配置source maps,需要配置devtool,有以下四种不同的配置选项:
source-map:在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度。
cheap-module-source-map:在一个单独的问价中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也是的浏览器开发者工具只能对应到具体的行,不能对应到具体的列,会对调试造成不便。
eval-source-map:使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的source map但是对打包后输出的js文件的执行具有性能和安全的影响。不过在开发阶段这是一个非常好的选项,但是在生成阶段一定不要用这个选项。
cheap-module-eval-source-map:这是在打包文件时最快的生成source map的方法,生成的source map会和打包后的js文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点。
具体使用例:
module.exports = {
devtool:"eval-source-map",//配置生成source map,是实际生成环境中不要用这个选项。
entry:__dirname+"/app/main.js",
output:{
path:__dirname+"/public",
filename:"bundle.js"
}
}
使用webpack构建本地服务器
如果希望浏览器检测代码的修改,并自动刷新修改后的结果,可以使用webpack提供的一个可选的本地开发服务器,这个服务器基于nodejs构建,可以是实现想要的功能。这个一个单独的组件,需要在webpack中进行配置之前,需要单独安装它作为项目依赖。
npm install --save-dev webpack-dev-server
devserver作为webpack配置选项中的一项,具有以下配置选项
contentBase:默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录,如public。
port:设置默认监听端口,如果省略,默认为“8080”。
inine:设置为true,当源文件改变时会自动刷新页面。
colors:设置为true,使终端输出的文件为彩色的。
historyApiFallback:在页面单页应用时非常有用,它依赖与HTML5 history API,如果设置为TRUE,所有的跳转将指向index.html。
在webpack配置文件中的具体使用为:
module.exports = {
devtool:"eval-source-map",
entry:__dirname+"/app/main.js",
output:{
path:__dirname+"/public",
filename:"bundle.js"
},
devServer:{
contentBase: "./public",//本地服务器所加载的页面所在的目录
colors:true,//终端中输出结果为彩色
historyApiFallback:true,//不跳转
inline:true//实时刷新
}
}
Loaders
通过使用不同的loader,webpack通过调用外部的脚步或工具可以对各种各样的格式的文件进行处理,比如说JSON文件并把它转换为js文件,或者把下一代的js文件(ES6,ES7)转换为现代浏览器可以识别的js文件。或者说对React的开发而言,合适的Loader可以把React的jsx文件转换为js文件。
loaders需要单独安装并且需要在webpack.config.js下的modules关键字下进行配置,loaders的配置选项包括以下几个方面:
test:一个匹配loaders所处理的文件的拓展名的正则表达式(必须)。
loader:loader的名称(必须)。
include/exclude:手动添加必须处理的文件/文件夹,或屏蔽不需要处理的文件/文件夹(可选)。
query:为loaders提供额外的设置选项(可选)。
实际使用:
npm install --save-dev json-loader
module.exports = {
devtool:"eval-source-map",
entry:__dirname+"/app/main.js",
output:{
path:__dirname+"/public",
filename:"bundle.js"
},
module:{ //在配置文件中添加JSON loader
loaders: [
{
test: /.json$/,
loader:"json-loader"
}
]
},
devServer:{
contentBase: "./public",
colors:true,
historyApi Fallback:true,
inline:true
}
}
新建json文件如config.json:
{
"greetText":"hello"
}
greeter.js修改为:
var config = require("./config.js");
module.exports = function(){
var greet=document.createElement('div");
greet.textContent=config.greetText;
}
Babel
babel是一个编译js的平台,通过编译可以达到以下目的:
下一代的js标准如ES6,ES7,这些标准目前并未被当前的浏览器完全支持。
使用基于js进行了拓展的预压,比如React的JSX。
babel其实是几个模块化的包,核心功能位于 babel-core的npm包中。webpack把它们整合在一起使用,但对于需要的功能和拓展,需要单独安装包,常用的是解析ES6的babel-preset-es2015和解析JSX的babel-preset-react。
首先,依赖这些需要的包:
npm install --save-dev babel-core babel-loader babel-preset-es2015 babel-preset-react
//模块之间用空格隔开
在webpack中配置babel,即在loaders里面配置
...
module:{
loaders:[
{
test:/.json$/,
loader:"json-loader"
},
{
test:/.js$/,
exclude:/node_modules/,
loader:'babel',
query:{
preset:['es2015','react']
}
}
]
}
...
babel里面的内容可以单独设置,写在文件。babelrc文件里面。
{
“presets”:['es2015','react']
}
css
webpack提供两个工具处理样式表,css-loader和style-loader。
css-loader使能够使用类似@import和url(...)的方法实现require()的功能。
style-loader将所有的计算后的样式加入页面中。
两者组合使用在一起使能够把样式表嵌入webpack打包后的js文件中。
先需要安装这两个组件:
npm install --save-dev style-loader css-loader
在webpack.config.js中的loaders里面添加:
{
text:/.css$/,
loader:'style!css' //添加对样式表的处理。这里的感叹号的作用在于使用同一文件能够使用不同类型的loader
}
在app文件夹中创建一个main.css的文件写样式。
由于webpack只有单一的入口,其他模块需要用import,require,url等导入到相关位置,因此要把css文件导入到‘main.js’中。
在main.js中添加 import './main.css'