简体   繁体   中英

Webpack React externals not working

I can't seem to get webpack's externals configuration for React correctly

The app works when react is imported as a vendor bundled from node_modules. But when I remove the vendor bundle and try to use react from a CDN I get the following error.

Warning: React.createElement: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: undefined. You likely forgot to export your component from the file it's defined in. printWarning @ react.js:3640 warning @ react.js:3664 createElement @ react.js:2357 module.exports @ app.js:122 webpack_require @ app.js:20 (anonymous) @ app.js:429 webpack_require @ app.js:20 module.exports @ app.js:66 (anonymous) @ app.js:69

Full Code at https://github.com/ericnoguchi/react-testing

Here is my webpack config

let LiveReloadPlugin = require('webpack-livereload-plugin');
let ExtractTextPlugin = require("extract-text-webpack-plugin");
let webpack = require('webpack');

module.exports = {
    entry: {
        'app': './@Client.js',
        // 'vendor': [
        //     "react",
        //     "react-dom",
        //     "react-router"
        // ],
    },
    output: {
        path: __dirname + '/_dist',
        publicPath: '/',
        filename: "[name].js"
    },
    externals: {
        "react": 'React',
        "react-dom": 'ReactDOM',
        "react-router": 'ReactRouter'
    },
    devServer: {
        contentBase: '_dist'
    },
    module: {
        loaders: [
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            },
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                query: {
                    presets: [
                        "react",
                        "es2015",
                        "stage-2"
                    ]
                }
            }
        ]
    },
    plugins: [
        new webpack.DefinePlugin({
            "process.env": {
                BROWSER: JSON.stringify(true)
            }
        }),
        // new webpack.optimize.CommonsChunkPlugin({
        //     name: 'vendor',
        //     filename: 'vendor.js',
        //     minChunks: Infinity
        // }),
        new ExtractTextPlugin("css/[name].css"),
        new LiveReloadPlugin()
    ]
};

And there is the layout component

import React, { Component } from 'react';
import { Link } from 'react-router'

// http://stackoverflow.com/questions/30347722/importing-css-files-in-isomorphic-react-components
if (process.env.BROWSER) {
  require('./layout.scss');
  console.log('lalala')
}

export class Layout extends Component {
  handleClick() {
    alert(0);
  }
  render() {
    let {custom, children} = this.props;
    return (
      <html>
        <head>
          <title>{custom.title}</title>
          <link rel="stylesheet" type="text/css" href="css/app.css" />
        </head>
        <body>
          <h1>{custom.title}</h1>
          <button onClick={this.handleClick}>Click me</button>
          {children}
          <ul>
            <li>
              <Link to="/">Index</Link>
            </li>
            <li>
              <Link to="/about">About</Link>
            </li>
            <li>
              <Link to="/foo">404</Link>
            </li>
          </ul>


          <script dangerouslySetInnerHTML={{
            __html: 'window.PROPS=' + JSON.stringify(custom)
          }}></script>
          {/*<script src="vendor.js"></script>*/}
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react.js" />
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.4.2/react-dom.js" />
          <script src="https://cdnjs.cloudflare.com/ajax/libs/react-router/3.0.2/react-router.js" />
          <script src="app.js" />
        </body>
      </html>
    );
  }
}

Client APP

import ReactDOM from 'react-dom';
import routes from './routes/routes.jsx'

ReactDOM.render(routes, document);

源地图出错

React is working just fine judging by the error you're pasting. Your problem is somewhere else.

There are however multiple flaws in your code. First of all it's not very common to generate the full page from React, and I see your html , head and body tags inside your render method.

Second, if you're loading the React CDN scripts from React, how is that supposed to work? :) It's a miracle you're getting that error at all.

Have an index.html with the basic HTML skeleton. If you're doing server-side rendering, have a simple template do the same and embed your server-side rendering of the React in a <div id="app"></div> placeholder.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM