Skip to content

Latest commit

 

History

History
358 lines (277 loc) · 8.29 KB

1.start-a-new-project.md

File metadata and controls

358 lines (277 loc) · 8.29 KB

怎样搭建一个基于 dva 的工程

在搭建之前确保已经安装最新版 nodejs

创建工程目录

安装 dva & roadhog

$ npm i dva-cli -g
$ dva -v
0.7.8
$ npm i roadhog -g
$ roadhog -v
0.5.3

创建项目

$ dva new newproject

启动项目

$ cd newproject
$ npm install
$ npm start

打开浏览器访问 http://localhost:8000/ 可以看到欢迎界面

Mac 系统, 如果出现权限问题 permission denied, open '/Users/用户名/.babel.json' 请使用 sudo chown -R 用户名 ~/.babel.json 解决

目录结构

.
├── dist                   # 编译结果
├── mock                   # 虚拟数据
├── public                 # 文件夹内所有文件将直接复制到根目录
├── src                    # Source directory
    ├── assets             # Store images, icons, ...
    ├── components         # UI components
    ├── index.css          # CSS for entry file
    ├── index.html         # HTML for entry file
    ├── index.js           # Enry file
    ├── models             # Dva models
    ├── router.js          # Router configuration
    ├── routes             # Route components
    ├── services           # Used for communicate with server
    └── utils              # Utils
        └── request.js     # A util wrapped dva/fetch
├── .editorconfig          #
├── .eslintrc              # Eslint config
├── .gitignore             #
├── .roadhogrc             # Roadhog config
└── package.json           #

配置文件

由于 dvaroadhog 的版本还没有稳定,用命令生成的新目录不能直接用于开发,需要修改配置文件。

package.json

关闭启动时自动开启浏览器新页签功能

  {
    ...
    "scripts": {
-     "start": "roadhog server",
+     "start": "roadhog server --no-open",
    },
    ...
  }

安装依赖并添加至 package.json

# lodash
$ npm i -D lodash
# babel-plugin
$ npm i -S babel-polyfill
$ npm i -D babel-plugin-import babel-plugin-lodash
# eslint-config
$ npm i -D eslint-config-promise
# webpack-plugin
$ npm i -D lodash-webpack-plugin html-webpack-plugin
# shim
$ npm i es5-shim console-polyfill

复制 es5-shim.min.js es5-sham.min.js console-polyfill/index.js 文件到 public 文件夹

console-polyfill/index.js 改名为 console-polyfill.js

新增 webpack.config.js 文件

当前版本 roadhog 功能不完善,不过幸好支持读取文件 webpack.config.js 修改配置。

import webpack from 'webpack';
import { isRegExp } from 'lodash';
import HtmlWebpackPlugin from 'html-webpack-plugin';
import ExtractTextPlugin from 'extract-text-webpack-plugin';
import LodashModuleReplacementPlugin from 'lodash-webpack-plugin';

// rucksack
// import rucksack from 'rucksack-css';

export default ( webpackConfig, env ) => {

  const loaders = webpackConfig.module.loaders;

  // rucksack
  // const postcss = webpackConfig.postcss;
  // webpackConfig.postcss = function () {
  //   return postcss().unshift( rucksack() );
  // };

  // 根目录使用相对地址
  webpackConfig.output.publicPath = '';

  // 不打包 moment.js 的语言包
  const noParse = webpackConfig.module.noParse;
  if ( Array.isArray( noParse ) ) {
    noParse.push( /moment.js/ );
  }
  else if ( noParse ) {
    webpackConfig.module.noParse = [ noParse, /moment.js/ ];
  }
  else {
    webpackConfig.module.noParse = [ /moment.js/ ];
  }

  // lodash
  webpackConfig.babel.plugins.push( 'lodash' );
  webpackConfig.plugins.push( new LodashModuleReplacementPlugin() );

  // 生成 HTML
  webpackConfig.module.loaders = loaders.filter(
    loader => isRegExp( loader.test ) && loader.test.toString() !== '/\\.html$/'
  );
  webpackConfig.plugins.push(
    new HtmlWebpackPlugin( {
      // favicon: './src/logo/logo.ico',
      template: './src/index.html',
      filename: 'index.html',
      inject: true

      // 方便实施人员修改配置 index.html 不压缩
      // minify: {  //压缩HTML文件
      //   removeComments: false,  //移除HTML中的注释
      //   collapseWhitespace: false  //删除空白符与换行符
      // }
    } )
  );

  // 打包配置
  if ( env === 'production' ) {

    // 字体打包
    loaders.unshift( {
      test: /\.(woff|woff2|ttf|eot)(\?v=\d+\.\d+\.\d+)?$/,
      loader: 'file',
      query: {
        name: 'static/[name].[hash:8].[ext]'
      }
    } );

    // 所有输出文件添加 hash
    webpackConfig.output.filename = '[name].[chunkhash:6].js';
    webpackConfig.output.chunkFilename = '[name].[chunkhash:6].js';

    // css common 添加 hash
    webpackConfig.plugins.forEach( ( plugin, index, plugins ) => {
      if ( plugin instanceof ExtractTextPlugin ) {
        plugins[ index ] = new ExtractTextPlugin( '[name].[chunkhash:6].css' );
      }
      else if ( plugin instanceof webpack.optimize.CommonsChunkPlugin ) {
        plugins[ index ] = new webpack.optimize.CommonsChunkPlugin(
          'common',
          'common.[chunkhash:6].js'
        );
      }
    } );

  }

  return webpackConfig;
};

详细的 webpack 配置参考 roadhogwebpack配置

注:官方不推荐此方法修改配置,因为不便于以后的完美升级。 由于官方的配置不能完全满足我们的需求,因此 webpack.config.js 配置还是必要的。 当根目录存在 webpack.config.js 文件时,运行服务会有警告。

.roadhogrc

详细文档参考 https://github.com/sorrycc/roadhog

不喜欢 json 格式的配置,可以改名为 .roadhogrc.js 使用 javascript 语法 支持 es6 语法

  {
+   "multipage": true,
-   "entry": "src/index.js",
+   "entry": ["src/common.js", "src/index.js"],
    ...
  }

.eslintrc

编辑器语法检查配置。

统一团队代码风格,调试方便,提高开发效率

  {
    ...
-   "extends": "airbnb"
+   "extends": "promise"
    ...
  }

Hello World

  1. src/index.html
  <!DOCTYPE html>
  <html lang="zh-CN">
  <head>
    <meta charset="utf-8">
    <meta name="renderer" content="webkit">
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
    <title></title>
    <!-- /path/to/ 或者 / -->
    <base id="basename" href="/" />
    <!--[if lt IE 10]>
    <script type="text/javascript" src="es5-shim.min.js"></script>
    <script type="text/javascript" src="es5-sham.min.js"></script>
    <script type="text/javascript" src="console-polyfill.js"></script>
    <![endif]-->
  </head>
  <body>
  <div id="root"></div>
  </body>
  </html>
  1. src/router.js
  import React from 'react';
  import { Router, Route } from 'dva/router';
  import IndexPage from './routes/IndexPage';

  function RouterConfig({ history }) {
    return (
      <Router history={history}>
        <Route path="/" component={IndexPage} />
      </Router>
    );
  }

  export default RouterConfig;
  1. src/routes/indexPage.jsx
  import React from 'react';
  import './IndexPage.less';

  function IndexPage() {
    return (
      <div style={{ textAlign: 'center' }}>
        <h1>Hello World</h1>
      </div>
    );
  }

  IndexPage.propTypes = {};

  export default IndexPage;
  1. src/routes/indexPage.less
  body {
    overflow: hidden;
  }
  1. src/index.js
  import dva from 'dva';
  import './index.css';

  // 1. Initialize
  const app = dva();

  // 2. Plugins
  // app.use({});

  // 3. Model
  // app.model(require('./models/example'));

  // 4. Router
  app.router(require('./router'));

  // 5. Start
  app.start('#root');
  1. src/common.js 打包公共库
  import 'dva';
  import 'react';
  import 'react-dom';
  import moment from 'moment';
  import 'moment/locale/zh-cn';

  // 全局设置 locale
  moment.locale( 'zh-cn' );
  1. 删除多与文件,启动开发服务器

    $ npm start

打开浏览器访问 http://localhost:8000/ 可以看到 Hello World