github代码:https://github.com/liuniansilence/react-webpack-frame
一. 添加package.json
默认已经有npm环境。若没有,先安装npm。
在新建文件夹slprj_v4下,用命令行添加package.json文件。
$ npm init
一路回车确定,完成package.json的建立。
最后一步回车(或输入yes)后,如果git命令行很久没有反应,但是文件夹已经出现package.json文件,可以直接用Ctrl+C取消此次命令。)
生成的package.json如下:
{
"name": "demoapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
二. 安装pkg
通过git命令安装pkg:
$ npm install react webpack --save-dev
如果网络比较慢,长时间没有回应,可以利用淘宝镜像来安装。
1). 安装淘宝镜像,命令行:
$ npm install -g cnpm --registry=https://registry.npm.taobao.org
2). 安装完成之后,我们就可以直接从淘宝NPM安装pkg:
// 命令行原本的npm要换成cnpm
$ cnpm install [name] --save-dev
// 如果要安装指定版本的pkg,可以在[name]之后本。如:
$ cnpm install webpack@2.6.0 --save-dev
// 卸载的时候可以用命令行uninstall。亲试npm uninstall的速度还是可以的
$ npm uninstall [name] --save-dev
–save-dev和–save的区别:–save-dev 是你开发时候依赖的东西,–save 是你发布之后还依赖的东西。比如,你写 ES6 代码,如果你想编译成ES5发布那么babel就是devDependencies。如果你用了jQuery,由于发布之后还是依赖jQuery,所以是dependencies。但是在npm里面除了二进制的依赖,似乎也不用区分是不是dev。因为使用npm就是自己编译的意思,而不使用npm直接拿编译后的版本的,这些依赖项也看不到。
3). pkg安装
"devDependencies": {
"antd": "^2.13.2",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"body-parser": "^1.17.2",
"cross-env": "^5.0.1",
"css-loader": "^0.28.4",
"happypack": "^4.0.0",
"html-webpack-plugin": "^2.29.0",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^3.0.0",
"style-loader": "^0.18.2",
"webpack": "^2.6.0",
"webpack-dev-server": "^2.8.2",
"webpack-hot-middleware": "^2.15.0",
"webpack-zepto": "0.0.1"
}
上述列举了搭建webpack+react+es6开发环境所需要的一些pkg,可以通过cnpm安装。
$ cnpm install [name] --save-dev
安装完成之后,可以在package.json中看到安装好的pkg。如下:
{
"name": "demoapp",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"antd": "^2.13.2",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"body-parser": "^1.17.2",
"cross-env": "^5.0.1",
"css-loader": "^0.28.4",
"happypack": "^4.0.0",
"html-webpack-plugin": "^2.29.0",
"less": "^2.7.2",
"less-loader": "^4.0.5",
"react": "^15.6.1",
"react-dom": "^15.6.1",
"react-router": "^3.0.0",
"style-loader": "^0.18.2",
"webpack": "^2.6.0",
"webpack-dev-server": "^2.8.2",
"webpack-hot-middleware": "^2.15.0",
"webpack-zepto": "0.0.1"
}
}
如果已经有别人的package.json文件,可以拷贝别人的文件后,在根目录下运行
// 用淘宝镜像的话,换成cnpm
$ cnpm install
// 已有node_modules, 生成package.json
$ npm init
三. 配置文件webpack.config.js
新建文件webpack.config.js,可以在其中对开发环境进行配置。大致如下:
var webpack = require('webpack');
module.exports = {
/*entry:{
page: "./src/app.js"
},*/
//修改entry
entry: [
// "webpack-dev-server/client?http://127.0.0.1:3000",
// "webpack/hot/only-dev-server",
"./app/main.js"
],
output: {
path: __dirname,
filename: "build/bundle.js",
publicPath: "/build"
},
module: {
loaders: [
{
test: /\.css$/,
exclude: /node_modules/,
loader: "style-loader!css-loader"
}, {
test: /\.less?$/,
loaders: [
'style-loader',
'css-loader',
'less-loader?{"sourceMap":false}'
],
exclude: /node_modules/
},{
test: /\.js[x]?$/,
exclude: /node_modules/,
loader: 'babel-loader?presets[]=env&presets[]=react'
}
]
},
resolve: {
extensions: ['.js', '.jsx']
},
plugins: [
new HappyPack({
id: 'jsx',
cache: true,
loaders: [{
path: 'babel-loader',
query: {
plugins: [
"transform-runtime", "transform-decorators-legacy", "add-module-exports"
],
presets: ['env', 'react', "stage-0"],
cacheDirectory: true
}
}],
threads: 6
}),
new webpack.NoErrorsPlugin(), //允许错误不打断程序
new webpack.HotModuleReplacementPlugin(), //webpack热替换插件
new webpack.ProvidePlugin({
"$": "webpack-zepto"
})
],
devtool: 'source-map',
webpackServer: { stats: 'errors-only', noInfo: true },
};
注意module->loaders中的配置。第一项test/.js?$/用来匹配解析js和jsx语法,可以解析react语法和es6语法;第二项解析css语法;第三项解析sass。
四. 常见bug
- Warning: Each child in an array or iterator should have a unique “key” prop.
这个是和react的dom-diff算法相关的。react对dom做遍历的时候,会根据data-reactid生成虚拟dom树。如果你没有手动的添加unique constant key的话,react是无法记录你的dom操作的。它只会在重新渲染的时候,继续使用相应dom数组的序数号(就是array[index]这种)来比对dom树。
解决方法:加一个叫做key的东西。
<ListItem key={node.imageUrl} imgUrl={node.imgUrl} onClick={redirect}></ListItem>
运行webpack编译命令报错,Module build failed.
语法错误,检查语法。
运行webpack编译命令报错,cannot find module.
一般为路径错误,检查引入文件的路径是否有错误。
编译通过,运行时控制台报错 unexpected token import.
使用了ES6中的语法import来加载文件。出现这种错误是因为缺少文件解析ES6的语法,重新设置配置文件 webpack.config.js