1. 程式人生 > >webpack react antd遇到的問題

webpack react antd遇到的問題

  1. 初始化專案檔案
  2. 加入antd
  3. 問題
  4. 總結
  5. 相關連結

最近這兩天把redux切換到了redux-saga之後,就想學習學習webpack. 咋說呢,這個東西被大家說的神乎其神,所以在我的認知裡還是蠻神祕的(新手的感覺而已,不喜勿噴).
今天上午把webpack看了下,有個大致的方向,就想配一個簡單的,可以本地開發執行的react(github custom_react)應用.

初始化專案檔案

  • package.json
    這個很簡單,直接npm init就好. npm?

  • index.html
    我們新建一個index.html

    .

mkdir -p public
cd public
touch index.html

index.html內容如下:

<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <meta name="theme-color" content="#000000"
>
<title>custom</title> </head> <body> <div id="root"></div> </body> </html>
  • index.js
    開始這個js檔案之前,我們需要使用相關的包
npm i --save react react-dom

然後我們的index.js是這樣的.

import ReactDOM from 'react-dom';
import App from './App';
import React from
'react' ReactDOM.render( <App/>, document.getElementById('root') );
  • App.js
    然後我們的App.js是這樣的.
import React, { Component } from 'react';

class App extends Component {
    render() {
        return (
            <h1>Hello Word</h1>
        )
    }

}

export default App
  • webpack.config.js
    同樣,在開始新建檔案之前, 先安裝相關的包.
npm i --save webpack 或者 npm i webpack -g
npm install --save-dev webpack-dev-server // webpack的伺服器
npm install --save-dev babel-core babel-loader  babel-preset-es2015 babel-preset-react babel-preset-stage-0
npm install --save-dev css-loader postcss-loader style-loader
npm install --save-dev autoprefixer

-g是全域性安裝,執行打包命令的時候直接webpack就好了.如果是--save安裝,就需要打包的時候使用 node_modules/.bin/webpack.在這裡,我們安裝了webpack以及bable家族.(利用bable去轉換es6,去轉換jsx, …).還有css相關的處理.

// webpack.config.js
var webpack = require('webpack');
var path = require('path')
module.exports = {
    entry: ['webpack/hot/dev-server', __dirname + "/index.js"],
    output: {
        path: __dirname + "/build",
        filename: "bundle.js",
        publicPath: "/assets/"
    },
    module: {
        loaders: [
            {
                test: /\.(js|jsx)$/, // test 匹配js和jsx)
                exclude: /node_modules/, //遮蔽不需要處理的檔案
                loader: 'babel-loader',
                query: {
                    "presets": [
                        "react",
                        "es2015",
                        "stage-0"
                    ],
                }
            },
            {
                test: /\.css$/,
                loader: 'style-loader!css-loader?importLoaders=1',
            }
        ]
    },
    plugins: [
        new webpack.HotModuleReplacementPlugin(), //模組的熱替換外掛
    ],
    devServer: {
        contentBase: path.join(__dirname, "/public"), // index.html的位置
        historyApiFallback: true,
        inline: true,
        port: 3008, //這裡寫你自己想要的啟動埠
        compress: true,
        progress: true,
    }
}

好的,目前我們的webpack.config.js大致就是這樣,現在我們還需要修改package.json去執行他.

// package.json
. . .
"scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "build": "webpack",
    "start": "webpack-dev-server"
  },
. . . 

現在我們可以在終端輸入命令嘗試.

npm run build //會去構建配置,會有檔案output.
npm start // 啟動專案.

請確定我們的index.html引入了檔案.

. . .
<body>
    <div id="root"></div>
    <script src="/assets/bundle.js"></script>
 </body>
. . .

不出意外,正常啟動,輸入localhost:3008之後,就會出現Hello Word!

加入antd

首先安裝相關的包

npm install antd --save
npm install babel-plugin-import --save-dev

然後在我們的webpack.config.js配置使用.

// webpack.config.js
. . .
query: {
                    "presets": [
                        "react",
                        "es2015",
                        "stage-0"
                    ],
                    plugins: [
                        ["import", {
                            libraryName: "antd",
                            style: "css"
                        }],
                    ]
                }
. . .

然後我們嘗試是否引入了antd.
- 修改App.js

import React, { Component } from 'react';
import MainLayout from './src/MainLayout'

class App extends Component {
    render() {
        return (
            <MainLayout />
        )
    }

}

export default App
  • src/MainLayout.js
import React from 'react'
import { Layout, Menu, Breadcrumb, Icon } from 'antd';
const {Header, Content, Footer, Sider} = Layout;
const SubMenu = Menu.SubMenu;


class SiderDemo extends React.Component {
    state = {
        collapsed: false,
    }


    onCollapse = (collapsed) => {
        console.log(collapsed);
        this.setState({
            collapsed
        });
    }

    render() {
        return (
            <Layout style={{
                minHeight: '100vh'
            }}>
        <Sider
            collapsible
            collapsed={this.state.collapsed}
            onCollapse={this.onCollapse}
            >
          <div className="logo" />
          <Menu theme="dark" defaultSelectedKeys={['1']} mode="inline">
            <Menu.Item key="1">
              <Icon type="pie-chart" />
              <span>Option 1</span>
            </Menu.Item>
            <Menu.Item key="2">
              <Icon type="desktop" />
              <span>Option 2</span>
            </Menu.Item>
            <SubMenu
            key="sub1"
            title={<span><Icon type="user" /><span>User</span></span>}
            >
              <Menu.Item key="3">Tom</Menu.Item>
              <Menu.Item key="4">Bill</Menu.Item>
              <Menu.Item key="5">Alex</Menu.Item>
            </SubMenu>
            <SubMenu
            key="sub2"
            title={<span><Icon type="team" /><span>Team</span></span>}
            >
              <Menu.Item key="6">Team 1</Menu.Item>
              <Menu.Item key="8">Team 2</Menu.Item>
            </SubMenu>
            <Menu.Item key="9">
              <Icon type="file" />
              <span>File</span>
            </Menu.Item>
          </Menu>
        </Sider>
        <Layout>
          <Header style={{
                background: '#fff',
                padding: 0
            }} />
          <Content style={{
                margin: '0 16px'
            }}>
            <Breadcrumb style={{
                margin: '16px 0'
            }}>
              <Breadcrumb.Item>User</Breadcrumb.Item>
              <Breadcrumb.Item>Bill</Breadcrumb.Item>
            </Breadcrumb>
            <div style={{
                padding: 24,
                background: '#fff',
                minHeight: 360
            }}>
              Bill is a cat.
            </div>
          </Content>
          <Footer style={{
                textAlign: 'center'
            }}>
            Ant Design ©2016 Created by Ant UED
          </Footer>
        </Layout>
      </Layout>
        );
    }
}

export default SiderDemo

然後我們npm start一下,應該是可以的了.

問題

怎麼說呢,其實這些東西都是可以找到的,但是因為版本等原因,難免會碰到一些小問題,那麼我今天就凱說這半天我碰到的兩個問題.
- Cannot GET /

這個問題倒是還好,被我猜測到了,是沒有執行起來,應該是說沒有找到index.html檔案,所以把伺服器當前工作地址指向index.html坐在的資料夾下. 我們這裡是在public資料夾下.

  • 頁面空白

頁面空白,不顯示Hello Word. 開啟瀏覽器console發現是沒有找到對應的bundle.js. 去sources裡也沒有對應的js檔案.這個也有人碰到過,看這個issue
所以,我們需要指定一下publicPath, 否則頁面是找不到的.

  • es6語法報錯

出現Module Build Faild相關的錯誤.就是es6的語法錯誤.找了很久都不行,最後在一篇外文裡看到了解決辦法(最後會放上鍊接).加上stage-0的支援就好了.

總結

目前碰到的問題就是那麼多,而且這個文章只適合一點點也不懂的朋友,還有很多東西需要去處理,比如生產模式,效能優化..,所以,還得一起繼續學習.

相關連結