Skip to content

Navigation Menu

Sign in
Sign up

Latest commit

History

19 Commits

Folders and files

NameName
Last commit message
Last commit date

Repository files navigation

文件夹说明

一步一步讲解react+webpack的配置(demo01)

看了很多博客,大都是把配置文件一笔带过,或者干脆不给出配置文件,然而环境搭建对于新手来说是既困难又重要,显然网络上的博客不利于新手开始学习。 BZ打算从从头开始,一步一步配置webpack,能够使用ES6+React组合开发,废话少说让我们一起来开始Webpack+ES6+React之旅。

可以在我的github 中clone或者fork https://github.com/zrysmt/react-demo

当然你也可以使用本博文最后总结的部分或者从我的github中获得,全部安装插件npm install,然后执行webpack就可以编译了。

  • 使用命令npm init新建包管理文件
  • 安装webpack ,npm i --save-dev webpack@1.13.3,注意:这里用的版本是1.x(@1.13.3)版本的。忽略(@1.13.3)直接下载的会是新版本的,写法会有些改变;
  • 在项目根目录下新增webpack.config.js文件,它的基本结构是:
var webpack = require('webpack');
module.exports = {
entry:{
page: "./src/app.js"
},
 output: {
 path: './build',
 filename: "bundle.js"
 },
 module: {
 loaders: [
 {test:/\.js$/,exclude: /node_modules/,loader:''},//加载器在这里
//下面我们会在这里增加
 ]
 }
};

1.支持es6

 npm i --save-dev babel-core babel-loader babel-preset-es2015

webpack.config.js

{ test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' }

.babelrc

{
 "presets": [
 "es2015"
 ]
}

入口app.js,es6语法

var p = require("./es6test/es6test1.js")
//es6test1.js
import Point from './es6test2';
let p = new Point(1,2);
console.log(p.toString()); 
//es6test2.js
class Point {
 constructor(x, y) {
 this.x = x;
 this.y = y;
 }
 toString() {
 return '(' + this.x + ', ' + this.y + ')';
 }
}
export default Point; 

2. 支持React语法

{test:/\.jsx$/,exclude: /node_modules/,loader:'jsx-loader?harmony'}

入口文件app.js

var React = require('react');
var ReactDOM = require('react-dom');
var HelloMessage = React.createClass({
 render: function() {
 return <h1>Hello {this.props.name}</h1>;
 }
});
ReactDOM.render( <HelloMessage name="John" />,
 document.getElementById('example')
);

3. React和es6同时支持

  • 安装
 npm i --save-dev babel-preset-react

注意:.babelrc文件和上面的是一样也是必须的。 webpack.config.js

{test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}},
//同时支持es6 react 或者下面的写法都可以
{test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'},
//同时支持es6 react

使用React,es6语法

import React from 'react';
import ReactDOM from 'react-dom';
class HelloMessage extends React.Component {
 render() {
 return <h1> Hello { this.props.name } </h1>;
 }
}
ReactDOM.render( <HelloMessage name="zry" />,
 document.getElementById('example')
);

4. 其余配置

css/sass

  • 安装
npm i --save-dev style-loader css-loader sass-loader node-sass
  • webpack.config.js
{ test: /\.css$/, loader: "style!css" },
{ test: /\.scss$/, loader: "style!css!sass" }, //sass加载器

使用很简单

import "./home/home.css";
import "./home/home.scss";

css文件可以独立出来

npm i --save-dev extract-text-webpack-plugin

配置

/*下面两行的作用是分离css*/
{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") },
{ test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass

图片加载

npm i --save-dev url-loader

配置webpack.config.js

{test: /\.(png|jpg)$/,
 exclude: /node_modules/,
 loader: 'url?limit=8192'}

意思是大于8192kb的图片会以base64的形式加载

使用:

<img src={require("./imgs/rect.png")}/>
//或者在css中直接使用
background: url(imgs/toolbar.png) no-repeat;

path路径管理

有时候在配置文件中经常会用到路径管理

npm i --save-dev path

在配置文件中

var path = require('path');
output: {
 path: path.resolve(__dirname, 'output'),
 },

5. 基本功能配置总结:

package.json

{
 "name": "react-demo",
 "version": "1.0.0",
 "description": "",
 "main": "index.js",
 "scripts": {
 "test": "echo \"Error: no test specified\" && exit 1",
 "start": "webpack-dev-server --hot --progress --colors",
 "build": "webpack --progress --colors"
 },
 "repository": {
 "type": "git",
 "url": "zry"
 },
 "author": "",
 "license": "ISC",
 "devDependencies": {
 "babel-core": "^6.18.0",
 "babel-loader": "^6.2.7",
 "babel-preset-es2015": "^6.18.0",
 "babel-preset-react": "^6.16.0",
 "css-loader": "^0.25.0",
 "jsx-loader": "^0.13.2",
 "node-sass": "^3.10.1",
 "react": "^15.3.2",
 "react-dom": "^15.3.2",
 "sass-loader": "^4.0.2",
 "style-loader": "^0.13.1",
 "webpack": "^1.13.3"
 }
}

webpack.config.js

var webpack = require('webpack');
module.exports = {
entry:{
page: "./src/app.js"
},
 output: {
 path: './build',
 filename: "bundle.js"
 },
 module: {
 loaders: [
 // { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader' },//支持es6
 // {test:/\.jsx?$/,exclude: /node_modules/,loader:'jsx-loader?harmony'},//支持react
 // {test:/\.jsx?$/,exclude: /node_modules/,loader:'babel?presets[]=react,presets[]=es2015'},//同时支持es6 react或者
 {test:/\.jsx?$/,exclude: /node_modules/,loader: 'babel', query: {presets: ['es2015', 'react']}},//同时支持es6 react
 {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'},
 /*下面两行的作用是分离css*/
 /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") },
 { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/
 { test: /\.css$/, loader: "style!css" },
 { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器
 ]
 },
 resolve: {
 extensions: ['', '.js', '.json']
 },
 plugins: [
 // new ExtractTextPlugin("output/[name].css"),//独立css文件
 new webpack.NoErrorsPlugin()
 ],
 devtool: 'source-map'
};

别忘了.babelrc文件

{
 "presets": [
 "es2015"
 ]
}

6. React支持热插拔

webpack-dev-server支持热插拔(热替换 HRM),使用HRM功能也有两种方式:命令行方式(推荐)和Node.js API 方式。

6.1 Node.js API方式

Node.js API方式需要做三个配置:

  1. webpack/hot/dev-server加入到webpack配置文件的entry项;
  2. new webpack.HotModuleReplacementPlugin()加入到webpack配置文件的plugins项;
  3. hot:true加入到webpack-dev-server的配置项里面。

使用 react 编写代码时,能让修改的部分自动刷新。但这和自动刷新网页是不同的,因为 hot-loader 并不会刷新网页,而仅仅是替换你修改的部分

  • 安装
npm i --save-dev react-hot-loader webpack-dev-server
  • 修改.babelrc
{
 "presets": [
 "es2015"
 ],
 "plugins":["react-hot-loader/babel"]
}
  • 修改webpack.config.js
var webpack = require('webpack');
module.exports = {
 //修改:entry
 entry: [
 "webpack-dev-server/client?http://127.0.0.1:3000",
 "webpack/hot/only-dev-server",
 "./src/app.js"
 ],
//修改:output
 output: {
 path: __dirname,
 filename: "build/bundle.js",
 publicPath: "/build"
 },
 module: {
 loaders: [
 { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react
 {test: /\.(png|jpg)$/, exclude: /node_modules/, loader: 'url?limit=8192'},
 /*下面两行的作用是分离css*/
 /*{ test: /\.css$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader") },
 { test: /\.scss$/, loader:ExtractTextPlugin.extract("style-loader", "css-loader!sass-loader") }, //sass加载器*/
 { test: /\.css$/, loader: "style!css" },
 { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器
 ]
 },
 resolve: {
 extensions: ['', '.js', '.json']
 },
 plugins: [
 // new ExtractTextPlugin("output/[name].css"),//独立css文件
 new webpack.NoErrorsPlugin(), //允许错误不打断程序
 new webpack.HotModuleReplacementPlugin() //增加:webpack热替换插件
 ],
 devtool: 'source-map'
};
  • 增加server.js文件
var webpack = require('webpack');
var WebpackDevServer = require('webpack-dev-server');
var config = require('./webpack.config');
new WebpackDevServer(webpack(config), {
 publicPath: config.output.publicPath,
 hot: true,
 historyApiFallback: true
}).listen(3000, 'localhost', function(err, result) {
 if (err) {
 return console.log(err);
 }
 console.log('Listening at http://localhost:3000/')
});

如何使用?--在命令行中

webpack &
node server.js //启动node服务

在浏览器输入localhost:3000即可查看结果,我们修改css文件,保存之后网页会自动刷新显示在浏览器上。js文件修改需要手动刷新一次。

6.2 命令行方式

命令行方式比较简单,需要加入--inline --hot。 例子位置在我的github

https://github.com/zrysmt/react-demo/tree/master/demo03

这个例子中执行的命令是:

SET DEBUG=true && webpack-dev-server --history-api-fallback --progress --profile --inline --colors --hot --port 8080 --open

指定端口8080,可以是其它的没有被占用过的任意端口。

具体配置项也有所改变

var webpack = require('webpack');
var path = require('path');
var HtmlwebpackPlugin = require('html-webpack-plugin');
// 定义当前是否处于开发debug阶段
var isDebug = JSON.stringify(JSON.parse(process.env.DEBUG || 'false'));
// 根据isDebug变量定义相关config变量
var configVarObj = {};
if(isDebug === 'true') {
 console.log('I am in debuging............');
 configVarObj = {
 htmlPath: 'index.html', // 定义输出html文件路径
 // devtool: 'cheap-source-map' // 生成sourcemap,便于开发调试
 devtool: 'eval' // 生成sourcemap,便于开发调试
 };
} else {
 console.log('I am in releasing............');
 configVarObj = {
 htmlPath: /*cjebTemplateFolder + */'/index.html', // 定义输出html文件路径
 devtool: ''
 };
}
module.exports = {
 context: path.join(__dirname, 'src'),
 entry: {
 app:"./app.js",
 vendors: [
 'jquery'
 ]
 },
 output: {
 path: path.resolve(__dirname, 'output'),
 // 输出文件名
 filename: 'js'+'/[name].min.js?[hash]',
 // cmd、amd异步加载脚本配置名称
 chunkFilename: 'js'+'/[name].chunk.js?[hash]',
 publicPath: ''
 },
 module: {
 loaders: [
 { test: /\.jsx?$/, exclude: /node_modules/, loader: 'babel', query: { presets: ['es2015', 'react'] } }, //同时支持es6 react
 { test: /\.css$/, loader: "style!css" },
 { test: /\.scss$/, loader: "style!css!sass" }, //sass加载器
 ]
 },
 resolve: {
 extensions: ['', '.js', '.jsx','.json']
 },
 devtool: configVarObj.devtool,
 plugins: [
 new HtmlwebpackPlugin({
 title: 'test',
 template: path.join(__dirname, './index.html'),
 filename: 'index.html',
 minify: {
 minifyJS: true,
 removeComments: true,
 minifyCSS: true
 },
 }),
 new webpack.optimize.UglifyJsPlugin({
 compress: {
 warnings: false
 }
 }),
 //定义全局变量
 new webpack.DefinePlugin({
 __DEV__: isDebug 
 })
 ]
};

可以在我的github https://github.com/zrysmt/react-demo中clone或者fork

参考阅读:

About

一步一步讲解react+webpack的配置;阮一峰React入门案例改造成使用ES6语法形式;React-router的一个完整例子

Resources

Stars

5 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages

AltStyle によって変換されたページ (->オリジナル) /