2017-04-04 115 views
5

好的。我正在引導一個簡單的應用程序。我正在使用flow.js。我使用的預設是babel-preset-2015,babel-preset-react和babel-preset-stage-0。我必須在我的.babelrc中放入相同的預置,並在我的webpack.config中放入所有的預置。如果我例如從webpack.config romove他們我得到一個錯誤'反應沒有定義'。如果我刪除.babelrc和babel-register,則會出現錯誤,因爲我使用了導入和Flow.js註釋。這是爲什麼發生?如果我把預設置於webpack.config中,我應該可以刪除.babelrc或反之。這是我的代碼現在看起來如何運作(減去一些對問題不重要的文件)。爲什麼我必須將babel-presets放入.babelrc和webpack.config.js中?

啓動dev.js

require('babel-register') 
require('./src/server/index.js') 

index.js

/* @flow */ 

import Express from 'express' 
import path from 'path' 
import conf from '../conf/' 

const APP_PORT: number = conf.APP_PORT 
const PORT = process.env.PORT || APP_PORT 

const app: Express = new Express() 

// Middleware 
app.set('views', path.join(__dirname, 'views')) 
app.set('view engine', 'ejs') 
app.use(Express.static(path.join(__dirname, '../', 'client', 'dist'))) 

// Routes 
app.get('*', function (req: Object, res: Object) { 
    res.render('index') 
}) 

app.listen(PORT, function() { 
    console.log(`Express server is up on port ${PORT}`) 
}) 

app.js

import React from 'react' 
import ReactDOM from 'react-dom' 

ReactDOM.render(
    <h1>First</h1>, 
    document.getElementById('app') 
) 

個的package.json

{ 
    "scripts": { 
    "start-dev": "set \"NODE_ENV=development\" && babel-node ./start-dev.js", 
    "start": "set \"NODE_ENV=development\" && node ./start-dev.js", 
    "flow": "./node_modules/.bin/flow check", 
    "standard": "node_modules/.bin/standard --verbose | node_modules/.bin/snazzy" 
    }, 
    "dependencies": { 
    "ejs": "^2.5.6", 
    "express": "^4.15.2", 
    "react": "^15.4.2", 
    "react-dom": "^15.4.2" 
    }, 
    "devDependencies": { 
    "babel-cli": "^6.24.0", 
    "babel-core": "^6.24.0", 
    "babel-eslint": "^7.2.1", 
    "babel-loader": "^6.4.1", 
    "babel-preset-es2015": "^6.24.0", 
    "babel-preset-react": "^6.23.0", 
    "babel-preset-stage-0": "^6.22.0", 
    "babel-register": "^6.24.0", 
    "eslint": "^3.18.0", 
    "eslint-config-standard": "^7.1.0", 
    "eslint-plugin-flowtype": "^2.30.4", 
    "eslint-plugin-react": "^6.10.3", 
    "flow-bin": "^0.42.0", 
    "snazzy": "^6.0.0", 
    "standard": "^9.0.2", 
    "webpack": "^2.3.2" 
    } 
} 

.babelrc

{ 
    "passPerPreset": true, 
    "presets": [ 
    "es2015", 
    "react", 
    "stage-0" 
    ] 
} 

webpack.config.babel.js

'use strict' 

import path from 'path' 
const publicPath = path.resolve(__dirname, './src/client') 

module.exports = { 
    devtool: '#source-maps', 
    performance: { 
    hints: false 
    }, 
    context: publicPath, 
    entry: { 
    bundle: './app.js' 
    }, 
    output: { 
    path: path.join(publicPath, 'dist'), 
    filename: '[name].js', 
    publicPath: '/dist/' 
    }, 
    resolve: { 
    extensions: ['.js', '.jsx'] 
    }, 
    module: { 
    rules: [ 
     { 
     test: /\.jsx?$/, 
     exclude: /node_modules/, 
     loader: 'babel-loader', 
     options: { 
      presets: [ 
      'react', 
      'es2015', 
      'stage-0' 
      ] 
     } 
     } 
    ] 
    } 
} 

回答

10

如果我把預置在webpack.config中,我應該可以刪除.babelrc或反之。

不,事實並非如此。在webpack配置中指定預設只會影響webpack,其他所有使用babel的預設(例如babel-nodebabel-register等)不會關心您的webpack配置,因此不會看到它們。

另一種方式確實有效。因此,如果您有.babelrc,則可以刪除webpack預設選項,因爲babel-loader在引擎蓋下使用了巴貝爾,這顯然尊重.babelrc

如果我例如將它們從webpack.config中刪除,我得到一個錯誤React is not defined

問題是您的.babelrc配置與webpack配置中的配置不同。罪魁禍首是"passPerPreset": true。有了這個選項,每個預置單獨應用而不考慮其他預設。爲此,訂單很重要。從babel docs - Plugin/Preset Ordering

預設排序顛倒(從上到下)。

這意味着它們將在下面的順序應用:stage-0reactes2015。由於它們分別應用,因此react會將JSX轉換爲React.createElement,因爲React位於範圍內,並且es2015將只將導入轉換爲_react2.default,因此不再定義React。兩束之間的整個DIFF是這樣的:

@@ -9470,7 +9470,7 @@ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { de 
// var React = require('react') 
// var ReactDOM = require('react-dom') 

-_reactDom2.default.render(React.createElement(
+_reactDom2.default.render(_react2.default.createElement(
    'h1', 
    null, 
    'Juhuuuu' 

沒有太多有關passPerPreset,但它在Release notes標記實驗和你應該完全避免。

雖然如果您將react預設置於列表中,它會起作用,但我建議刪除passPerPreset選項,除非您有一個非常具體的理由來使用它。

{ 
    "presets": [ 
    "es2015", 
    "react", 
    "stage-0" 
    ] 
} 
+0

謝謝邁克爾,那工作。把反應放在.babelrc的第一位,我能夠從config.js中刪除預設,它仍然有效。爲了更好的理解,我只有幾個問題。如果我從start-dev.js文件的頂部刪除babel-register,它不起作用。 ** babel-register **和**。babelrc **之間的關係和** babel-register **和** babel-node **之間有什麼不同?據寫道,使用** babel-register **和** babel-node **對於生產不利,並且在部署之前提前編譯會更好。什麼是最好的方式來做到這一點? –

+0

'babel-register'會傳輸您導入的任何文件,而'babel-node'只會傳輸您正在運行的文件,而不是所有由它導入的文件。除非你明確地告訴它不要(例如使用['--no-babelrc'標誌](https://babeljs.io/docs/usage)),否則所有正式屬於babel的部分都將遵守'.babelrc'中的配置。/CLI /#巴貝爾-忽略-babelrc))。要構建生產,可以使用'babel-cli',參見[編譯目錄](https://babeljs.io/docs/usage/cli/#babel-compile-directories)。 Webpack也可以用來綁定後端。 –

+0

好的。我想我正在得到它。所以在開發中,如果我用babel-register或babel-node測試它,實際上並不重要。在生產中最好只使用babel。我剛纔嘗試過,我還有最後一個問題。在使用babel-cli之後,我得到了一個lib文件夾,其中包含我在項目中的所有文件夾,包括新的bundle.js。我總是使用webpack來製作一個bundle.js,然後在index.html裏面,我有一個

0

嘗試和修改您的裝載機像

module: { 
    rules: [ 
     { 
     test: /\.jsx?$/, 
     exclude: [/node_modules/], 
     use: [{ 
      loader: 'babel-loader', 
      options: { presets: ['react','es2015', 'stage-0'] } 
     }], 
     } 
    ] 
    } 
+0

這不符合的WebPack 2. resolve.extensions 此選項不再需要傳遞一個空字符串不再需要。此行爲已移至resolve.enforceExtension。請參閱解決更多用法。 –

+0

嘗試更新的答案 –

+0

謝謝,但沒有運氣。如果我把它像這樣,並刪除.babelrc我得到一個錯誤意外的令牌導入 –

相關問題