webpack配置React开发环境(上)
Webpack 是一个前端资源加载/打包工具,我们部门的一条主要技术栈就是Webpack+React+ES6+node,虽然之前自己做个人项目也接触好多次Webpack,但是自己并没有研读总结过Webpack的知识点,读了wepack-demos,这些demos虽然是基于webpack@1.x的,但是举例得蛮简洁明了,所以这次就简单翻译此文的一些重点。
什么是Webpack?
Webpack是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能,并且如果有需要它还可以被整合到其他比如 Grunt / Gulp 的工作流。
安装 Webpack:npm install -g webpack。
Webpack 使用一个名为 webpack.config.js
的配置文件。
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
一些你应该知道的命令:
- webpack —— 进行一次编译
- webpack -p —— 进行一次编译(压缩成一行)
- webpack --watch —— 持续编译
- webpack -d —— 编译完成后包含一个maps文件
- wepack --colors —— 使压缩文件变漂亮(我暂时没看出来)
在开发应用程序时,可以在package.json文件中编写scripts字段,如下所示:
// package.json
{
// ...
"scripts": {
"dev": "webpack-dev-server --devtool eval --progress --colors",
"deploy": "NODE_ENV=production webpack -p"
},
// ...
}
入口文件
入口文件是一个Webpack将会读取它并将它编译成bundle.js的文件
demo01:单个入口文件:
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
}
};
demo02:多个入口文件:(它对多页面app是非常有用的)
// index.html
<html>
<body>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html> // webpack.config.js
module.exports = {
entry: {
bundle1: './main1.js',
bundle2: './main2.js'
},
output: {
filename: '[name].js'
}
};
Babel-loader
加载器是预处理器,它转换您的应用程序的资源文件(更多信息)。例如,Babel-loader可以将JSX / ES6文件转换为JS文件。官方文档有一个完整的加载器列表。
// webpack.config.js
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=es2015&presets[]=react'
},
]
} 或者
module: {
loaders: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel',
query: {
presets: ['es2015', 'react']
}
}
]
}
CSS-loader
Webpack允许您在JS文件中引用CSS,然后使用CSS-loader预处理CSS文件。
// main.js
require('./app.css');
// webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.css$/, loader: 'style-loader!css-loader' },
]
}
};
注意,你必须使用两个加载器来转换CSS文件。首先是CSS-loader读取CSS文件,另一个是Style-loader将Style标签插入HTML页面。不同的装载器通过感叹号(!)链接。
启动服务器后,index.html将具有内部样式表。(demo04)
Image loader
// main.js
var img1 = document.createElement("img");
img1.src = require("./small.png");
document.body.appendChild(img1); var img2 = document.createElement("img");
img2.src = require("./big.png");
document.body.appendChild(img2); // index.html
<html>
<body>
<script type="text/javascript" src="bundle.js"></script>
</body>
</html> // webpack.config.js
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
module: {
loaders:[
{ test: /\.(png|jpg)$/, loader: 'url-loader?limit=8192' }
]
}
};
url-loader转换图像文件。如果图像大小小于8192字节,则将其转换为数据URL;否则,它将被转换为正常的URL。如你所见,问号(?)用于将参数传递到加载器。
启动服务器后,small.png和big.png将有以下URL。
<img src="data:image/png;base64,iVBOR...uQmCC">
<img src="4853ca667a2b8b8844eb2693ac1b2578.png">
UglifyJS Plugin(减少输出)
Webpack有一个插件系统来扩展其功能。例如,UglifyJs Plugin将缩小输出(bundle.js)JS代码。(demo07)
// webpack.config.js
var webpack = require('webpack');
var uglifyJsPlugin = webpack.optimize.UglifyJsPlugin;
module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new uglifyJsPlugin({
compress: {
warnings: false
}
})
]
};
压缩的效果如下:
// 压缩前
var longVariableName = 'Hello';
longVariableName += ' World';
document.write('<h1>' + longVariableName + '</h1>'); // 压缩后
var o="Hello";o+=" World",document.write("<h1>"+o+"</h1>")
自动打开浏览器&&自动创建index.html
此演示向您演示如何加载第三方插件。 html-webpack-plugin可以为您创建index.html,并且当Webpack加载时,open-browser-webpack-plugin可以打开一个新的浏览器选项卡。
// main.js
document.write('<h1>Hello World</h1>'); // webpack.config.js
var HtmlwebpackPlugin = require('html-webpack-plugin');
var OpenBrowserPlugin = require('open-browser-webpack-plugin'); module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [
new HtmlwebpackPlugin({
title: 'Webpack-demos',
filename: 'index.html'
}),
new OpenBrowserPlugin({
url: 'http://localhost:8080'
})
]
};
环境标志
您可以仅在具有环境标志的开发环境中启用一些代码(demo09)
// main.js
document.write('<h1>Hello World</h1>'); if (__DEV__) {
document.write(new Date());
} // index.html
<html>
<body>
<script src="bundle.js"></script>
</body>
</html> // webpack.config.js
var webpack = require('webpack'); var devFlagPlugin = new webpack.DefinePlugin({
__DEV__: JSON.stringify(JSON.parse(process.env.DEBUG || 'false'))
}); module.exports = {
entry: './main.js',
output: {
filename: 'bundle.js'
},
plugins: [devFlagPlugin]
};
然后现在将环境变量传递到webpack。
# Linux & Mac
$ env DEBUG=true webpack-dev-server # Windows
$ set DEBUG=true
$ webpack-dev-server
Common chunk(抽出公用脚本)
当多脚本具有公共块时,可以使用CommonsChunkPlugin将公共部分提取到单独的文件中。
// main1.jsx
var React = require('react');
var ReactDOM = require('react-dom'); ReactDOM.render(
<h1>Hello World</h1>,
document.getElementById('a')
); // main2.jsx
var React = require('react');
var ReactDOM = require('react-dom'); ReactDOM.render(
<h2>Hello Webpack</h2>,
document.getElementById('b')
); // index.html
<html>
<body>
<div id="a"></div>
<div id="b"></div>
<script src="init.js"></script>
<script src="bundle1.js"></script>
<script src="bundle2.js"></script>
</body>
</html> // webpack.config.js
var CommonsChunkPlugin = require("webpack/lib/optimize/CommonsChunkPlugin");
module.exports = {
entry: {
bundle1: './main1.jsx',
bundle2: './main2.jsx'
},
output: {
filename: '[name].js'
},
module: {
loaders:[
{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
}
},
]
},
plugins: [
new CommonsChunkPlugin('init.js')
]
}
Vendor chunk
您还可以使用CommonsChunkPlugin从脚本中将供应商库提取到单独的文件中。(优化代码层面)
// main.js
var $ = require('jquery');
$('h1').text('Hello World'); // index.html
<html>
<body>
<h1></h1>
<script src="vendor.js"></script>
<script src="bundle.js"></script>
</body>
</html> // webpack.config.js
var webpack = require('webpack'); module.exports = {
entry: {
app: './main.js',
vendor: ['jquery'],
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.optimize.CommonsChunkPlugin(/* chunkName= */'vendor', /* filename= */'vendor.js')
]
};
如果你想要一个模块作为变量在每个模块,如使$和jQuery可用在每个模块没有写require(“jquery”)。你应该使用ProvidePlugin(官方文档)。
// main.js
$('h1').text('Hello World'); // webpack.config.js
var webpack = require('webpack'); module.exports = {
entry: {
app: './main.js'
},
output: {
filename: 'bundle.js'
},
plugins: [
new webpack.ProvidePlugin({
$: "jquery",
jQuery: "jquery",
"window.jQuery": "jquery"
})
]
};
热更新
热模块替换(HMR)交换,添加或删除模块,而应用程序正在运行,而没有页面重新加载。
您有两种方法通过webpack-dev-server启用热模块更换。
(1)在命令行中指定--hot和--inline
$ webpack-dev-server --hot --inline
选项的含义:
- --hot: 添加HotModuleReplacementPlugin并将服务器切换到热模式。
- --inline: 将webpack-dev-server运行时嵌入到bundle中。
- --hot --inline: 还添加了webpack/hot/dev-server条目。
(2)修改webpack.config.js文件(demo15)
- 添加新webpack.HotModuleReplacementPlugin() 的插件
- 添加webpack/hot/dev-server 和 webpack-dev-server/client?http://localhost:8080 到输入字段
// webpack.config.js
var webpack = require('webpack');
var path = require('path'); module.exports = {
entry: [
'webpack/hot/dev-server',
'webpack-dev-server/client?http://localhost:8080',
'./index.js'
],
output: {
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
module: {
loaders: [{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader',
query: {
presets: ['es2015', 'react']
},
include: path.join(__dirname, '.')
}]
}
};
// App.js
import React, { Component } from 'react'; export default class App extends Component {
render() {
return (
<h1>Hello World</h1>
);
}
} // index.js
import React from 'react';
import ReactDOM from 'react-dom';
import App from './App'; ReactDOM.render(<App />, document.getElementById('root')); // index.html
<html>
<body>
<div id='root'></div>
<script src="/static/bundle.js"></script>
</body>
</html>
有用的链接
- Webpack docs
- webpack-howto
- Diving into Webpack
- Webpack and React is awesome
- Browserify vs Webpack
- React Webpack cookbook
下回会学习总结webpack2的配置相关总结,有不错的文章欢迎分享。
webpack配置React开发环境(上)的更多相关文章
- 搭建 webpack、react 开发环境(三)
配置 react-router-dom 我们开发一个 React 工程肯定不是一两个“页面”就可以满足需求的,所以我们需要一个在多个“页面”中跳转的功能,在使用 React 构建的单页面应用中,要 ...
- 搭建 webpack、react 开发环境(二)
配置处理样式文件 到目前为止,整个工程的配置已经差不多了,对于 React 更多相关的配置将在后面继续介绍,现在我们先来对目前的工程进行优化. 前面我们学习了搭建 webpack.react 开发 ...
- 搭建 webpack、react 开发环境(一)
基本介绍 Webpack 是一个前端资源加载/打包工具.它将根据模块的依赖关系进行静态分析,然后将这些模块按照指定的规则生成对应的静态资源,它可以将多种静态资源 JavaScript.css.le ...
- 详解 Webpack+Babel+React 开发环境的搭建
1.认识Webpack 构建应用前我们先来了解一下Webpack, Webpack是一个模块打包工具,能够把各种文件(例如:ReactJS.Babel.Coffeescript.Less/Sass等) ...
- Webpack配置区分开发环境和生产环境
在项目开发的时候,我们通常会将程序分为开发环境和生产环境(或者叫线上环境),开发环境通常指的是我们正在开发的这个阶段所需要的一些环境配置,也就是方便我们开发人员调试开发的一种环境:生产环境通常指的是我 ...
- 使用dvajs+webpack构建react开发环境
之前我有写过博文介绍过dva.js及其用法,dva.js固然是个非常优秀的框架,但是如果用dev-cli来创建的话就会默认绑定使用roadhog而不是webpack.鉴于roadhog的文档要明显少于 ...
- 基于webpack的react开发环境搭建新手教程
最近学习react-webpack项目搭建,找到一篇我认为不错的博客,跟着学习了一番,写得很详细很好,本篇博客纯属记录总结,要看更详细的搭建过程及解析,请戳: 基于webpack的React项目搭建( ...
- 使用webpack搭建react开发环境
安装和使用webpack 1.初始化项目 mkdir react-redux && cd react-redux npm init -y 2.安装webpack npm i webpa ...
- 【webpack结合React开发环境配置】React开发环境配置之Webpack结合Babel8.x版本安装的正确姿势(Webpack最新版4.x结合Babel8.x环境配置步骤)
1. 安装cnpmnpm install -g cnpm --registry=https://registry.npm.taobao.org[使用淘宝镜像]2. 初始化package.json文件c ...
随机推荐
- linux下简单限制网卡速度
Linux下限制网卡的带宽,可用来模拟服务器带宽耗尽,从而测试服务器在此时的访问效果. 1.安装iproute yum -y install iproute 2.限制eth0网卡的带宽为50kbit: ...
- js原生之一个面向对象的应用
function IElectricalEquipment() { } IElectricalEquipment.prototype = { poweron: fu ...
- Bootstrap兼容IE8
使用BootStrap3.x写的公司一个响应式项目在IE下面错误百出,经过一番折腾.全部解决了IE8下的兼容问题. 这里汇总一下,希望对大家有所帮助. 1. Bootstrap UI整体在IE8下变窄 ...
- Failed to register Grid Infrastructure type ora.mdns.type
安装11g的集群软件的时候,在最后运行root.sh脚本时候,没有执行成功,最后提示如下错误: [root@r2 ~]# /u01/app/11.2.0/grid_1/root.sh Performi ...
- JQuery操作元素的属性与样式及位置 复制代码
<script type="text/javascript" src="JQuery/jquery-1.5.1.js"></script> ...
- We Chall-Training: Get Sourced-Writeup
MarkdownPad Document html,body,div,span,applet,object,iframe,h1,h2,h3,h4,h5,h6,p,blockquote,pre,a,ab ...
- WEB安全测试通常要考虑的测试点
1问题:没有被验证的输入测试方法: 数据类型(字符串,整型,实数,等)允许的字符集 最小和最大的长度是否允许空输入参数是否是必须的重复是否允许数值范围特定的值(枚举型)特定的模式(正则表达式) 2问题 ...
- linux之sed的常用操作
Sed命令: sed是一种流编辑器,它是文本处理中非常中的工具,能够完美的配合正则表达式使用,功能不同凡响.处理时,把当前处理的行存储在临时缓冲区中,称为"模式空间"(patter ...
- c语言中,有符号数位移
#include <stdio.h> int main(void) { unsigned i = 0xcffffff3; long j=0xcffffff3; int k=0xcfffff ...
- Bootstrap记录
左侧 导航下拉: <li class="dropdown"> <a href="#" class="dropdown-toggle& ...