why webpack
因为React和Redux开发课程中都要到了webpack构建.:cry:
* 将多个js文件 Bundle 成单一文件
* 在前端程代码中使用 npm packages
* 可以编写 JavaScript ES6 或 ES7(需 babel 來转译)
* Minify 压缩或优化代码
* 将 LESS 或 SCSS 转换成 CSS
* 支持 HMR(Hot Module Replacement)热加载
* 支持将任意类型文件加入到 JavaScript 中
* 其他更多…
webpack教程
一、环境配置
step0: 必须有node环境
本机必须先安装node
环境,可命令行键入:node -v
//查看是否安装&node版本信息
step1:创建react项目并初始化npm管理包(package.json)
- mkdir 01basicDemos 创建项目目录
- npm init –yes 初始化npm管理包,
--yes
是默认确认了所有package包信息
step2: 添加依赖和插件
//1、本地webpack构建和webpack构建服务端
npm install --save webpack webpack-dev-server
//2、react核心库
npm install --save react react-dom
//3、babel转译用es6编写的React
npm install --save-dev babel-core babel-loader babel-preset-react babel-preset-es2015
//4、转译css样式
npm install --save-dev style-loader css-loader
//5、转译sass(SASS-loader)
npm install --save-dev sass-loader node-sass
//6、单独打包 CSS
npm install --save-dev extract-text-webpack-plugin
//7、转译image图片
npm install --save-dev url-loader
//8、转译Json格式数据
npm install --save-dev json-loader
//9、指定网页的模板,并将转译后输出的`xxx.js`插入`inject`到`index.html`中的插件
npm install html-webpack-plugin --save-dev
step3、npm script构建脚本
"scripts": {
"dev": "webpack-dev-server --progress --config webpack.config.dev.js",
"prod": "webpack -p --progress --config webpack.config.prod.js"
}
使用构建命令
npm run dev //构建开发环境包
npm run prod //构建生产环境包
二、webpack教程介绍
包括dev
开发环境构建的webpack.config.dev.js
和prod
生产环境构建的webpack.config.prod.js
section1、转译ES6编写的React(Babel-loader)
- 1、webpack.config.js中转译配置,
test: /\.js[x]?$/
匹配正则, x可省, 即配置jsx/js为后缀的文件
loaders: [
{test: /\.js[x]?$/, exclude: /node_modules/, loader: 'babel-loader'}
]
- 2、转译
React
和ES6
语法,项目目录下新建babel转译配置文件.babelrc
{
"presets": ["react", "es2015"]
}
或者不需要.babelrc
,只需要在webpack.config.js中转译配置如下:
query: The query setting can be used to pass Additional options to the loader.
loaders: [
{test: /\.js[x]?$/,exclude: /node_modules/,loader: 'babel',
query: {presets: ['es2015', 'react']}
}
]
section2、多入口文件(Multiple entry files)
webpack.config.js中多入口配置
module.exports = {
entry: {
bundle1: './index.jsx',
bundle2: './testMultiEntry.js'
},
output: {
filename: '[name].js'
}
};
section3、转译CSS样式文件(CSS-loader)
- CSS-loader读取Css文件
- Style-loader将样式标签插入Html网页中
用
!
来链式调用多个loader, 执行顺序由右到左, 即先执行css-loader再到style-loader
index.jsx
import IndexCss from './styles/index.css';
index.css
body {
background-color: rgb(200, 56, 97);
}
webpack.config.js
loader: [ { test: /\.css$/, loader: 'style-loader!css-loader' } ]
section4、转译sass(SASS-loader)
index.jsx
import BgCss from './styles/bg.scss';
bg.scss
$bg-color: #ddd;
body {
background: {
color: $bg-color
};
}
webpack.config.js
{ test: /\.scss$/, loaders: 'style-loader!css-loader!sass-loader' }
section5、Css模块化(CSS Module)
css-loader?modules
让CSS模块化
即CSS文件默认是本地作用域,当然可以用
:global(...)
来套成全局.
app.css
.h1 {
color:red;
}
:global(.h2) {
color: blue;
}
App.jsx
import StyleCss from './../styles/app.css';
<h1 className={StyleCss.h1}>Hello World</h1>
<h2 className="h2">Hello Webpack</h2>
webpack.config.js
{ test: /\.css$/, loader: 'style-loader!css-loader?modules' }
section6、单独打包 CSS
把 CSS 从 js 文件当中独立出来.
webpack.config.prod.js
var ExtractTextPlugin = require('extract-text-webpack-plugin');
plugins: [ new ExtractTextPlugin("style.css") ]
loaders: [ { test: /\.(css|scss)$/,
loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules!sass-loader') },
]
plugins: [ new ExtractTextPlugin("[name].css") ]
section7、转译图片(Image loader)
App.jsx
import SmallImgSrc from './../../public/small.png';
import BigImgSrc from './../../public/big.png';
//指定src
<img src={SmallImgSrc} />
<img src={BigImgSrc} />
webpack.config.js
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
服务器加载后,可以看到`small.png` 和 `big.png`被转成如下:用
?
传参设置限制limit
字节,当图片小于8192字节时,图片会转成Data URL;否则将转成正常的URL格式.
<img src="data:image/png;base64,iVBOR...uQmCC">
<img src="4853ca667a2b8b8844eb2693ac1b2578.png">
section8、转译json格式数据(Json loader)
testMultiEntry.js
import ContactsData from './../../public/contacts.json'; //获取json数据
//打印出json格式中数据
console.log(ContactsData.datas);
webpack.config.js
{ test: /\.json$/, loader: 'json-loader' }
section9、网页模板插件html-webpack-plugin
指定网页的模板,并将转译后输出的xxx.js
插入inject
到模板网页中的插件.
不设置fileName默认输出和template同名,不设置inject默认插入body.
webpack.config.js
var HtmlWebpackPlugin = require('html-webpack-plugin')
var htmlWebpackPluginConfig = new HtmlWebpackPlugin({
template: __dirname + '/src/index.html',
filename: 'index.html',
inject: 'body'
});
plugins: [htmlWebpackPluginConfig]
section10、压缩js插件(UglifyJs Plugin)
webpack.config.prod.js
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
plugins: [
new uglifyJsPlugin({ compress: { warnings: false }
}),
new webpack.optimize.OccurrenceOrderPlugin()
]
- webpack.optimize.UglifyJsPlugin - Minify 压缩代码,并显示警告信息
- 也可以加入 OccurrenceOrderPlugin。
通过发生的次数 module 和 chunk 的 id。一些常用的 Id 取得较低(短)的 id。这使得 id 可以预测,减小大小.
section11、抽离公共js部分(Common chunk)
webpack.config.js
// 抽离公共js部分
var webpack = require('webpack');
var commonsPlugin = new webpack.optimize.CommonsChunkPlugin('common.js');
plugins: [ commonsPlugin ]
section12、热加载两种方式(Hot Module Replacement)
(1) 设置devServer
devServer: {
contentBase: "./dist",
inline: true,
port: 8888,
colors: true,
historyApiFallback: true
}
- contentBase: 默认以根目录挂到服务端
- port: 默认端口8080
- inline: 为ture,修改代码后会自动刷新浏览器显示最新代码
- historyApiFallback: 使用html5的history的API,不匹配的路由都会打开/
(2) 添加HotModuleReplacementPlugin插件
- 添加
new webpack.HotModuleReplacementPlugin()
到plugins
插件区域 - 添加
webpack/hot/dev-server
和webpack-dev-server/client?http://localhost:8080
到entry
入口区域
webpack.config.dev.js
var webpack = require('webpack');
module.exports = {
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
'./index.js'
],
plugins: [
new webpack.HotModuleReplacementPlugin()
]
};
section13、省略文件后缀名
如:可以 import ‘./myJSFile’ 而不需要指定文件后缀 import ‘./myJSFile.jsx’
resolve: {
extensions: ['.js', '.jsx']
}
只是赶脚有后缀可以直接看清楚是什么类型文件,所以demos中webpack.config.js并不添加使用resolve.
section14、环境标识符(Environment flags)
testMultiEntry.js
// 测试开发环境
if (__DEV__) {
console.log('这是在开发环境下');
}
webpack.config.dev.js
var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
});
plugins: [devFlagPlugin]
package.json
env DEBUG=true webpack-dev-server
参考资源
- 官方文档
- 中文指南
- webpack-demos
作者: ruanyf
- Webpack for React
书: pro react书
- webpack使用优化
from: AlloyTeam
- webpack收藏系列
from: github