Contents

最近一直在研究React,在了解完React的一些写法和Flux构建之后,自然开始想要让自己的代码更加模块化一点,或者说组件化一点。我希望自己今后的目录应该是图1这个样子。

图1

图中项目采用了Flux构架,因此会有actions|stores|utils,并且不同Router会映射到不同pages,而体现组件化的就是components文件夹,其结构如图2所示。

图2

可以看到里面包含两个组件,每个组件又包含了不同逻辑、视图。我觉得这样来进行应用的编写更能够凸显图3中对于组件化的定义。

图3

这样一来就需要采用一些比较自动化的构建工作流,既然采用了React,那么就必然绕不开webpack,而就在前一年,gulp又那么火,所以我这里主要有两种情况,分别由于我不同的目的。

##webapck
关于webpack的介绍如下:

Webpack是一个前端资源加载/打包工具,只需要相对简单的配置就可以提供前端工程化需要的各种功能,并且如果有需要它还可以被整合到其他比如 Grunt / Gulp 的工作流。

我的配置如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
var webpack = require('webpack');
var path = require('path');
var ExtractTextPlugin = require("extract-text-webpack-plugin");
var HtmlWebpackPlugin = require('html-webpack-plugin');
var indexPath = path.resolve(__dirname, 'src/index.js');
var outputPath = path.resolve(__dirname, 'public');
module.exports = {
entry: [
'webpack/hot/dev-server',
indexPath
],
output: {
path: outputPath,
filename: 'bundle.js'
},
devtool: 'source-map',
'display-error-details': true,
module: {
loaders: [
{
test: /\.js?$/,
exclude: /node_modules/,
loaders: ['react-hot', 'babel?presets[]=react,presets[]=es2015,presets[]=stage-0']
},
{
test: /.less$/,
loader: ExtractTextPlugin.extract('css!less')
},
{
test: /\.(jpg|png|mp3|svg)$/,
loaders: ['file?name=assets/[name].[ext]']
}
]
},
plugins: [
// new webpack.HotModuleReplacementPlugin(),
new webpack.NoErrorsPlugin(),
new webpack.optimize.CommonsChunkPlugin("commons", "commons.js"),
new webpack.ProvidePlugin({
'React': path.resolve(__dirname, "node_modules/react/react"),
'ReactDOM': path.resolve(__dirname, "node_modules/react-dom/dist/react-dom"),
"jQuery": path.resolve(__dirname, "node_modules/jquery/dist/jquery"),
"$": path.resolve(__dirname, "node_modules/jquery/dist/jquery")
}),
new ExtractTextPlugin("[name].css?[hash]-[chunkhash]", {
allChunks: true,
disable: false
}),
new HtmlWebpackPlugin({
title: 'React Blog in ES6',
template: './src/index.html'
})
]
};

首先是在entry上定义入口文件,然后再output定义生成文件,loaders里面是对于不同的文件的采用的loader。

对于React需要用到babel来进行转化,并且preset应该有react、es2015和stage-0。这样就可以在文件中按照es6的写法来写react了,会方便很多,因为es6提供了很多新的语法糖,还是挺适合React的。

另外,对于不同styles可以采用不同loader,比如我采用的less那么就需要使用css和less的loader。对于一些静态文件,比如图片、svg等,则需要用到fileloader。

最后就是一些插件,CommonsChunkPlugin用来将一些反复依赖的到第三方插件全部打包到一个common文件中,并且可以别名的形式出现,这样就不需要再文件中反复出现import React from 'react'这样的引用,顺便可以在eslint中将这些规则关闭,可以节省一定的代码量。ExtractTextPlugin和HtmlWebpackPlugin这两个插件可以生成html文件并且自动引用样式文件。

这样一来,在package.json文件中,只要在scripts就可以这样写:

"scripts": {
    "build": "webpack --progress --colors --watch",
    "dev": "webpack-dev-server --progress --hot --inline --colors --content-base build",
    "dist": "NODE_ENV=production webpack --progress --colors"
}

就可以很方便地进行热开发已经最后的部署等操作。

Contents