基于 NodeJS 的一个著名第三方模块,主要目的是来实现前端模块化和自动化的,在这之前还有一个跟它类似的 gulp ,也是一个自动化构建工具,主要功能是打包合并压缩重命名等...
webpack 其实也是一套自动化构建工具,在打包代码的时候也是跟 gulp 很相似的
左边比较多的文件(模块),也比较多的格式(js,css,html,jsx,scss),右边文件比较少,大部分都是转为JS格式,还有一些图片格式,所以 webpack 其实处理各种类型的文件,最终想把他们尽可能的转为JS类型的文件(打包,合并,压缩),webpack 多变少(或一个),多文件进少文件或者单文件出,而 gulp 更多的是多文件变相同多的文件,多进多出
一般开发目录是在entry
里面,发布是在output
文件夹
-
在根目录下新建
webpack.config.js
-
用npm安装
webpack
的依赖包,全局安装一次,本地也安装一次
npm install webpack -g
npm install webpack-cli -g
- 往配置文件里面写对应的配置
四大概念
- 入口(entry)
- 输出(output)
- loader
- 插件(plugins)
跟我们的gulp
的gulp.src()
,入口其实就是要导入需要处理的文件,放文件名
在webpack.config.js
同级目录下,新建entry
文件夹
// 配置参数
module.exports = {
// 入口 把index.js导入进来处理
entry: './entry/index.js'
};
在webpack.config.js
同级目录下,新建output
文件夹
const path = require('path');
// 配置参数
module.exports = {
// 入口 把index.js导入进来处理
entry: './entry/index.js',
output: {
// 写一段路径,寻找output文件夹
path: path.resolve(__dirname, 'output'),
// 在output文件夹里面导出文件名为bundle.js
filename: 'bundle.js'
}
};
在入口文件夹entry
的index.js
里面写入以下代码
import $ from "jquery";//记得先安装 npm install jquery
$("body").html("helloworld");
- 编译
在webpack.config.js
文件夹的命令行里面执行webpack
命令,如果成功的话会在output
文件夹下生成一份新的bundle.js
webpack
require.js
模块化,分开模块管理项目,并且能重复使用模块
webpack = gulp + requirejs
既做打包合并也做模块化,相对于gulp
,它就是更偏重于模块化
vue-cli
基于webpack
,它就的模块化就是基于webpack的
webpack 它默认只能处理JS类型文件,它不自带处理其他非JS文件的功能,如果你想 webpack 处理非 JS 类型文件,必须安装其他第三方插件来实现,webpack 里面这种插件称之为loaders
(加载器)
loader = 处理各种非JS类型文件
这个功能类似于 gulp 的拓展功能,需要装第三方插件
gulp-sass
gulp-minify
gulp-concat
比如.vue
组件是非JS类型文件,我们就需要安装vue-loader
来处理,类似的还有以下这些
npm install vue-loader
npm install sass-loader
npm install html-loader
npm install css-loader
npm install json-loader
安装完对应的loader之后,还需要在webpack.config.js
文件里面进行配置
这些loader都是帮你处理不同类型的文件(非JS类型文件),test
是正则,匹配文件名字,use
是加上你对应loader
的名字
module: {
rules: [{
test: /\.vue$/,
use: 'vue-loader'
}, {
test: /\.css$/,
use: ['style-loader', 'css-loader']
}, {
test: /\.png|jpg|jpeg$/,
use: ['url-loader']
}]
},
--your project
|--app
|--components
|--productBox.jsx
|--main.js
|--build
|--index.html
|--bundle.js(该文件是webpack打包后生成的)
默认已经安装了NodeJS,推荐用cnpm
npm install --save-dev react react-dom --save-dev
npm install -g webpack --save-dev//建议webpack全局安装,方便我们后面使用webpack命令
Babel其实是一个编译JavaScript的平台,它的强大之处表现在可以通过编译帮你达到以下目的:
下一代的JavaScript标准(ES6,ES7),这些标准目前并未被当前的浏览器完全的支持; 使用基于JavaScript进行了拓展的语言,比如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
在项目根目录下新建.babelrc
文件,就是只有后缀名的文件,添加如下代码
//.babelrc
{
"presets": [
"react",
"es2015"
]
}
讲到这里,我们基本上就可以迅速搭建一个简单的web项目,但不得不提的是webpack loader。它是我个人认为相比于其他模块加载更牛X的地方,将它用于react的开发,结合react与生俱来的优越性能,两者天衣无缝的配合简直就是黄金组合。
总的来说 webpack 的 loader可以实现:
可以将React JSX语法转为js语句 React开发中支持ES6语法 支持通过import来直接引入css、less、sass甚至是图片 支持css中引用的图片大小在某一大小范围之内直接转为BASE64格式等等等
为了能够让以上功能奏效,我们要先安装对应的: babel-loader
npm install babel-loader --save-dev
//css-loader
npm install css-loader --save-dev
//less-loader
npm install less-loader --save-dev
//style-loader
npm install style-loader --save-dev
//url-loader
npm install url-loader --save-dev
而具体的实现,我们只要在下面webpack的配置文件中加入module属性里的loaders:
webpack.config.js 是 webpack 的配置文件
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
module.exports = { //注意这里是exports不是export
devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map
entry: __dirname + "/app/main.js", //唯一入口文件
output: { //输出目录
path: __dirname + "/build", //打包后的js文件存放的地方
filename: 'bundle.js', //打包后的js文件名
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选)
loader: 'babel-loader'
//npm install babel-loader
//npm install babel-core
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=25000'
}]
}
};
使用 Source Maps,使调试更容易
devtool选项 | 配置结果 |
---|---|
source-map | 在一个单独的文件中产生一个完整且功能完全的文件。这个文件具有最好的source map,但是它会减慢打包文件的构建速度 |
cheap-module-source-map | 在一个单独的文件中生成一个不带列映射的map,不带列映射提高项目构建速度,但是也使得浏览器开发者工具只能对应到具体的行,不能对应到具体的列(符号),会对调试造成不便 |
eval-source-map | 使用eval打包源文件模块,在同一个文件中生成干净的完整的source map。这个选项可以在不影响构建速度的前提下生成完整的sourcemap,但是对打包后输出的JS文件的执行具有性能和安全的隐患。不过在开发阶段这是一个非常好的选项,但是在生产阶段一定不要用这个选项 |
cheap-module-eval-source-map | 这是在打包文件时最快的生成source map的方法,生成的Source Map 会和打包后的JavaScript文件同行显示,没有列映射,和eval-source-map选项具有相似的缺点 |
新版本推荐使用ES6书写React组件
var React = require('react');
//旧版本的写法,会有警告
/*var ProductBox = React.createClass({
render: function() {
return(
<div className = "productBox" >
Hello World!
</div>
);
}
});*/
//新版本的写法 推荐
class ProductBox extends React.Component {
render() {
return(
<div>Hello World!</div>
)
}
}
module.exports = ProductBox;
index.html是最终要呈现的页面文件,代码如下
<!DOCTYPE html>
<html>
<head lang="en">
<meta charset="UTF-8">
<title>React Test</title>
</head>
<body>
<!--要插入React组件的位置-->
<div id="content"></div>
<script src="bundle.js"></script>
</body
</html>
main.js是入口文件,用来将React组件放在真正的html中
var React = require('react');
var ReactDom = require('react-dom');
var AppComponent = require('./components/productBox.jsx');
ReactDom.render(
<AppComponent / >
, document.getElementById('content')
);
package.json是一个标准的npm说明文件,里面蕴含了丰富的信息,包括当前项目的依赖模块,自定义的脚本任务等
{
"devDependencies": {
"babel-core": "^6.24.1",
"babel-loader": "^7.0.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"less-loader": "^4.0.3",
"react": "^15.5.4",
"react-dom": "^15.5.4",
"style-loader": "^0.16.1",
"url-loader": "^0.5.8",
"webpack": "^2.4.1"
}
}
在命令行执行webpack
命令
想不想让你的浏览器监测你都代码的修改,并自动刷新修改后的结果,其实Webpack提供一个可选的本地开发服务器,这个本地服务器基于node.js构建,可以实现你想要的这些功能,不过它是一个单独的组件,在webpack中进行配置之前需要单独安装它作为项目依赖
npm install --save-dev webpack-dev-server
在webpack.config.js增加devServer的配置
//__dirname是node.js中的一个全局变量,它指向当前执行脚本所在的目录
module.exports = { //注意这里是exports不是export
devtool: 'eval-source-map', //生成Source Maps,这里选择eval-source-map
entry: __dirname + "/app/main.js", //唯一入口文件
output: { //输出目录
path: __dirname + "/build", //打包后的js文件存放的地方
filename: 'bundle.js', //打包后的js文件名
},
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/, //屏蔽不需要处理的文件(文件夹)(可选)
loader: 'babel-loader'
//npm install babel-loader
//npm install babel-core
}, {
test: /\.css$/,
loader: 'style-loader!css-loader'
}, {
test: /\.less$/,
loader: 'style-loader!css-loader!less-loader'
}, {
test: /\.(png|jpg)$/,
loader: 'url-loader?limit=25000'
}]
},
devServer: {
contentBase: './build', //默认webpack-dev-server会为根文件夹提供本地服务器,如果想为另外一个目录下的文件提供本地服务器,应该在这里设置其所在目录(本例设置到"build"目录)
historyApiFallback: true, //在开发单页应用时非常有用,它依赖于HTML5 history API,如果设置为true,所有的跳转将指向index.html
inline: true, //设置为true,当源文件改变时会自动刷新页面
port: 8080, //设置默认监听端口,如果省略,默认为"8080"
}
};
在命令行执行webpack-dev-server
命令就会运行服务器
webpack-dev-server
如果需要停止服务,在终端按两次ctrl+c
-
webpack和gulp的区别
-
webpack的四大概念入口(entry)输出(output)loader插件(plugins)
-
webpack如何实现模块化的
-
webpack的打包后执行代码的原理
eval("console.log(1)")