利用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

相關文章
相關標籤/搜索