利用Webpack+React(antd)+ES6+python(flask)实现代码转换

    以前的几篇博客是将flask 结合 antd本地化,可是这样使得antd没法按需加载(也不支持ES6的语法),并且在写的过程当中还须要把每一个组件都用antd对象,这样的作法虽然是实现了antd的本地化,可是没法最大化的使用antd组件库,最好的方式就是官网上的组件代码直接拿过来用就行,今天所作的就是这个功能。css

首先是借用Webpack ,它是当下最热门的前端资源模块化管理和打包工具。它能够将许多松散的模块按照依赖和规则打包成符合生产环境部署的前端资源。还能够将按需加载的模块进行代码分隔,等到实际须要的时候再异步加载。html

1、安装webpack1.安装webpack(项目根目录下):前端

$npm install webpack --save-dev

2.Webpack须要某些配置才能完成给他的工做。因此咱们须要在项目根目录下建立一个webpack.config.js的配置文件。写入如下内容:node

 
 
var webpack = require('webpack');
var path = require('path');

var APP_DIR = path.resolve(__dirname, 'static/components');
var BUILD_DIR = path.resolve(__dirname, 'static/js');

var config = {
  entry: APP_DIR + '/index.jsx',
  output: {
    path: BUILD_DIR,
    filename: 'bundle.js'
  }
};

module.exports = config;
 

Webpack的配置最少须要两项,一个是入口属性,一个是输出属性。APP_DIR指向React项目的代码所在目录,BUILD_DIR指向打包后文件的输出目录。react

就如同配置项名称所表达的同样。entry是打包所须要的入口文件。若是你对静态语言,好比c/c++之类的熟悉的话。这个入口文件就是c/c++包含main方法的文件。Webpack支持多个入口文件。这里目录static/components里的index.jsx文件就是整个应用的入口文件。webpack

output指明webpack在打包完成后须要作什么。这里,使用static/js目录存放打包后生成的文件bundle.jsc++

在static/components目录下建立文件index.jsx。并添加以下代码:git

console.log('Hello World!');

在terminal里输入下面的命令。github

$ ./node_modules/.bin/webpack -d

命令会调用webpack,生成开发环境下的bundle.js文件以及关联的map文件bundle.js.map。这两个文件都在配置文件制定的目录static/js下。web

可是目前只看到了编译以后的js文件,不够直观。在目录templates下建立一个index.html文件。这样js文件是否加载成功都能看到了。

<!DOCTYPE html>
<html>
  <head>
      <meta charset="UTF-8" />
      <title>webpack</title>
  </head>
  <body>
    <div id="ES6Box"></div>
    <script src="/static/js/bundle.js">
    </script>
  </body>
</html>

若是成功将会看到“Hello World!”。

2、使用Babel-Loader

    babel-loader使得EM2015以及React语法经过webpack翻译之后生成浏览器所识别的代码:

1.使用npm安装babel-loader。

$ npm install babel-loader babel-preset-es2015 babel-preset-react --save-dev

babel-preset-es2015babel-preset-reactbabel-loader使用的插件。专门用来翻译JSX和ES2015语法。安装以后还须要配置一下才能使用。

项目根目录下建立一个.babelrc的文件,并添加一下内容。

{
    "presets": ["es2015", "react"]
}

2.告诉webpack使用babel-loader来打包文件。
打开webpack.config.js并添加以下内容。

var webpack = require('webpack');
var path = require('path');

var APP_DIR = path.resolve(__dirname, 'static/components');
var BUILD_DIR = path.resolve(__dirname, 'static/js');

var config = {
  entry: {
    index1: APP_DIR + '/index.jsx',
    react1: APP_DIR + '/react.jsx',
    //多个文件可在后面追加。。。
  },
  output: {
    path: BUILD_DIR,
    filename: '[name].js'       //全部编译的文件都在static/js,文件名为entry设定的name,上面两个文件编译完之后为index1.js\react1.js。
  }, module: { rules: [ { test:
/\.jsx$/, use: [ 'babel-loader', ], include: [ // path.resolve(__dirname, "app") APP_DIR ], }], } }; module.exports = config;
loaders属性对应的值是一个数组。不过咱们只是用 babel-loader。每个加载器都须要经过 test属性指定能够处理的文件的后缀。 babel-loader用来处理 .js.jsx文件。 include属性指定处理哪一个目录下的文件。 loader属性就是加载器的名称。
3.安装react和react-dom
$ npm install react react-dom --save
这个时候就能够测试一下是否实现了,把刚刚建的index.jsx内容更改成react代码:
import React from 'react';
import {render} from 'react-dom';

class App extends React.Component {
    render() {
        return <p> Hello World! </p>
    }
}

render(<App />, document.getElementById('app'));

执行命令:

$ ./node_modules/.bin/webpack -d

成功之后便可看到Hello World!。

4.webpack监视文件变化,实时更新

$ ./node_modules/.bin/webpack -d --watch

ps:若是在实际项目时,运行终端时候启动服务以及占去一个终端,这个时候咱们能够另起一个终端来监视文件变化,这样两边互不干扰。

3、使用antd组建

  在从上面步骤作下来已经实现了浏览器支持react和ES6的语法了,下面是引入antd组件库》

1.安装:

$ npm install antd --save

这个时候你会发现pakage.json中你安装的全部东西都在里面。

{
  "name": "webpack-example",
  "version": "1.0.0",
  "description": "A simple webpack example.",
  "main": "bundle.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "webpack"
  ],
  "author": "jiang",
  "license": "MIT",
  "devDependencies": {
    "babel-loader": "^6.4.1",
    "babel-plugin-import": "^1.1.1",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-stage-1": "^6.22.0",
    "webpack": "^2.3.2"
  },
  "dependencies": {
    "antd": "^2.8.3",
    "react": "^15.4.2",
    "react-dom": "^15.4.2"
  }
}

2.引用antd

  将index.jsx中的内容换为antd官网中的任意一个组件代码,此处以表格为例:

import React from 'react';
import ReactDOM from 'react-dom';
import Form from 'antd/lib/form';
import Icon from 'antd/lib/icon';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';
const FormItem = Form.Item;


function hasErrors(fieldsError) {
  return Object.keys(fieldsError).some(field => fieldsError[field]);
}

class HorizontalLoginForm extends React.Component {
  componentDidMount() {
    // To disabled submit button at the beginning.
    this.props.form.validateFields();
  }
  handleSubmit = (e) => {
    e.preventDefault();
    this.props.form.validateFields((err, values) => {
      if (!err) {
        console.log('Received values of form: ', values);
      }
    });
  }
  render() {
    const { getFieldDecorator, getFieldsError, getFieldError, isFieldTouched } = this.props.form;

    // Only show error after a field is touched.
    const userNameError = isFieldTouched('userName') && getFieldError('userName');
    const passwordError = isFieldTouched('password') && getFieldError('password');
    return (
      <Form layout="inline" onSubmit={this.handleSubmit} style={{marginTop:50,marginLeft:50}}>
        <FormItem
          validateStatus={userNameError ? 'error' : ''}
          help={userNameError || ''}
        >
          {getFieldDecorator('userName', {
            rules: [{ required: true, message: 'Please input your username!' }],
          })(
            <Input prefix={<Icon type="user" style={{ fontSize: 13 }} />} placeholder="Username" />
          )}
        </FormItem>
        <FormItem
          validateStatus={passwordError ? 'error' : ''}
          help={passwordError || ''}
        >
          {getFieldDecorator('password', {
            rules: [{ required: true, message: 'Please input your Password!' }],
          })(
            <Input prefix={<Icon type="lock" style={{ fontSize: 13 }} />} type="password" placeholder="Password" />
          )}
        </FormItem>
        <FormItem>
          <Button
            type="primary"
            htmlType="submit"
            disabled={hasErrors(getFieldsError())}
          >
            Log in
          </Button>
        </FormItem>
      </Form>
    );
  }
}

const WrappedHorizontalLoginForm = Form.create()(HorizontalLoginForm);

ReactDOM.render(<WrappedHorizontalLoginForm />,document.getElementById('ES6Box'));

在引进的过程当中须要注意几点,注意上面的红色代码:

import React from 'react';
import ReactDOM from 'react-dom';
import Form from 'antd/lib/form';
import Icon from 'antd/lib/icon';
import Button from 'antd/lib/button';
import Input from 'antd/lib/input';

第1、二两行是引入React和ReactDOM,不然浏览器会报ReactDOMReact没有定义的错误。

后面则是antd的按需加载,也能够借用插件 babel-plugin-import

完成上面操做之后若是出现语法错误,不支持ES6的箭头函数或者其余语法

须要下载bable转码器:

$ npm install --save-dev babel-preset-stage-1

 

在.babelrc文件中添加规则:

{
    "presets": [
      "latest",
      "react",
      "stage-2"
    ],
    "plugins": []
  }

这个时候刷新页面会发现没有css样式:

别着急这个时候就须要加入antd的css,须要在webpack中添加css-loader/stylr-loader,方法很简单:

1.安装css-loader style-loader:

$npm install css-loader style-loader

2.在配置文件中加入依赖,package.json中添加安装的css-loader style-loader,注意版本必定要相同:

{
  "name": "webpack-example",
  "version": "1.0.0",
  "description": "A simple webpack example.",
  "main": "bundle.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "keywords": [
    "webpack"
  ],
  "author": "jiang",
  "license": "MIT",
  "devDependencies": {
    "babel-loader": "^6.4.1",
    "babel-plugin-import": "^1.1.1",
    "babel-preset-es2015": "^6.24.0",
    "babel-preset-react": "^6.23.0",
    "babel-preset-stage-1": "^6.22.0",
    "webpack": "^2.3.2"
  },
  "dependencies": {
    "antd": "^2.8.3",
    "react": "^15.4.2",
    "react-dom": "^15.4.2",
    "css-loader": "^0.27.3",
    "style-loader": "^0.16.1"
  }
}

添加之后须要从新执行命令:npm install 更新一下。

3.在webpack.config.js中添加进来:

var webpack = require('webpack');
var path = require('path');

var APP_DIR = path.resolve(__dirname, 'static/components');
var BUILD_DIR = path.resolve(__dirname, 'static/js');

var config = {
  entry: {
    index: APP_DIR + '/index.jsx',
    react: APP_DIR + '/react.jsx',
  },
  output: {
    path: BUILD_DIR,
    filename: '[name].js'
  },
  module: {
    rules: [
      {
        test: /\.jsx$/,
        use: [
          'babel-loader',
        ],
        include: [
          // path.resolve(__dirname, "app")
          APP_DIR
        ],
      },
      { test: /\.css$/,
        use: [ 'style-loader', 'css-loader' ] }
      ],
    }
};

module.exports = config;

最后在index.jsx中加入css:

import 'antd/dist/antd.css'; 

从新执行命令./node_modules/.bin/webpack -d就ok了:

这样就所有实现了antd真正的本地化,能够随心所遇的运用其官网上组件的代码了。

友情提示:过程虽然漫长而复杂,可是研究出来的一瞬间会让你以为值得。。。

 

借鉴:

http://blog.csdn.net/future_challenger/article/details/52389812

http://webpackdoc.com/index.html

相关文章
相关标签/搜索