从零开始搭建React同构应用(二)
项目工程化(浏览器端)
在从零开始React同构开发(一)中我们已经能实现基本的React配置和编译了。接下来我们需要将编译工作工程化。
代码
代码在这,建议下载后,对照着看,因为文章不方便把所有的代码贴上来
主要内容
项目目录结构优化
stylus 样式文件的处理和打包
extract-text-webpack-plugin 配置
html-webpack-plugin 配置
配置browser-sync 自动刷新(利用es6的decoratort 特性)
项目目录结构优化
先看下整理后的目录结构
src
├─config //附加webpack配置文件
├─module
│ ├─common //公共模块
│ │ └─stylus
│ ├─index //首页模块
│ │ ├─component
│ │ └─stylus
│ │ └─img
│ └─TodoDetail //todo详情模块
│ └─stylus
└─template //HTML模版
module 文件夹放置了各个模块,我把页面以模块分类,每个模块下第一层的.jsx 文件就是页面的入口文件(common除外)。
common模块文件夹放置一些公共组件、公共库、公共样式等。
template文件夹用于放置html-webpack-plugin 用到的页面模版。
当然我还在探索更好的目录配置方式,大家如果有想法欢迎@我^_^。
添加npm script
我们先添加一条watch 命令,用于开发环境的编译。
"scripts": {
"watch": "webpack -d -w --progress --colors --bs","test-server": "anywhere -p 18341 -d ./build"
},
样式文件处理
css、stylus文件的处理
前篇文章我们只编译了jsx,我们还没引入样式,假设现在项目的css使用stylus 来编写。那么可以参考以下配置。 我们需要3个loader:
stylus-loader
autoprefixer-loader
css-loader
vue-style-loader
file-loader 和url-loader
这些loaders大家肯定耳熟能详啦,可能大家会对vue-style-loader 会有疑惑,这里解释下:
因为在启用sourceMap 的情况下,style-loader 对background-image 属性没有处理好,生成的URL链接开头为chrome:// urls ,官方库中已经有人提issue了,。
后来尤雨溪大神fork了官方库后开发了vue-style-loader ,完美的解决了background-image 问题,当时发现这个库的时候真的感动的不行啊。。。
下面看一下样式文件loader的配置
loaders: [
{
test: /.(png|jpe?g|gif)/,loader: 'url?limit=1024&name=img/[name].[ext]'
},{
test: /.(ttf|eot|svg)$/,loader: "url?limit=1024&name=fonts/[name].[ext]"
},{
test: /.jsx?$/,exclude: /node_modules/,loader: "babel"
},{
test: /.(styl|css)$/,loader: "vue-style!css?sourceMap!autoprefixer!stylus")
},]
这样就可以愉快的在js中引入CSS啦
extract-text-webpack-plugin 配置
有时候我们需要把CSS提取出来,单独打包成一个文件,这时候需要用到extract-text-webpack-plugin
修改webpack.config.js
const ExtractTextPlugin = require("extract-text-webpack-plugin");
然后修改我们原有的styl-loader 配置
{
test: /.(styl|css)$/,loader: ExtractTextPlugin.extract(["vue-style"],"css?sourceMap!autoprefixer!stylus")
},
我们还要在plugin字段配置输出的CSS文件名称
plugins:[
new ExtractTextPlugin('css/[name].css'),]
执行watch 命令
`npm run watch`
可以看到css都被提取出来成为单独的文件了。
html-webpack-plugin 配置
作用:
自动生成HTML
自动在HTML引入js ,css 。
自动添加hash。
我们在src/config 新建html-webpack-plugin.config.js文件,由于配置HTML编译。
//html-webpack-plugin.config.js
const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = [
new HtmlWebpackPlugin({
filename: 'index.html',chunks: ['common','index'],template: path.resolve(__dirname,'../template/base.html'),hash: true,}),]
修改webpack.config.js
执行watch 命令
npm run watch
可以看到webpack帮我们自动生成了html文件。
index.html 文件内容如下:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width,initial-scale=1.0,minimum-scale=1.0,maximum-scale=1.0,user-scalable=0"/>
<title>React同构开发Demo</title>
<link href="/css/index.css?d8b82face5e26195ca7e" rel="stylesheet">
</head>
<body>
<div id="wrap"></div>
<script type="text/javascript" src="/js/common.js?d8b82face5e26195ca7e"></script>
<script type="text/javascript" src="/js/index.bundle.js?d8b82face5e26195ca7e"></script>
</body>
</html>
配置browser-sync 自动刷新
这里我们用到ES7的修饰器特性。目前transform-decorators 只有第三方的实现。
以Index.jsx为例
-
先修改babel.rc 文件: {
"presets": [
"react","es2015"
],"plugins": [
"transform-regenerator","transform-decorators-legacy" //添加这个
]
}
在config文件夹添加browser-sync.config.js
修改webpack.config.js
在common文件夹添加bs.js
在React组件中引入bs.js
执行watch 命令
`npm run watch`
刷新浏览器,看到下图说明自动刷新服务已经成功开启
webapck小技巧
减小路径的书写量
resolve: {
extensions: ['.jsx','.js',''],alias: {
'common': path.join(__dirname,'module/common')
}
},
自动引入库,不用每次都写import
new webpack.ProvidePlugin({
React: 'react',ReactDOM: 'react-dom',fetch: 'isomorphic-fetch',promise: 'promise'
}),
区分生产和开发环境
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify(process.env.NODE_ENV) || JSON.stringify('development'),
使用cross-env 来跨平台设置环境变量
"scripts": {
"watch": "webpack -d -w --progress --colors --bs","test-server": "anywhere -p 18341 -d ./build","dist": "cross-env NODE_ENV='production' webpack -p"
}
提取公共js、css
new webpack.optimize.CommonsChunkPlugin({
name: 'common',filename: 'js/common.js', (编辑:李大同)
【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!
|