来自CDN的Webpack,React-router和React

时间:2016-10-31 20:09:11

标签: javascript reactjs webpack react-router

我使用Webpack捆绑我的React应用程序和react-router进行路由。 ReactJs从CDN加载为外部库。我从react-router收到此错误消息,我不确定是否可以使用从CDN加载的React和其他反应库。

    PropTypes.js:8

    Uncaught TypeError: Cannot read property 'PropTypes' of undefined(…)
    (anonymous function) @ PropTypes.js:8
    __webpack_require__ @ bootstrap 2b8bebf…:19
    (anonymous function) @ index.js:15
    __webpack_require__ @ bootstrap 2b8bebf…:19
    (anonymous function) @ index.jsx:3
    __webpack_require__ @ bootstrap 2b8bebf…:19
    (anonymous function) @ bootstrap 2b8bebf…:39
    (anonymous function) @ bootstrap 2b8bebf…:39

enter image description here

的index.html

<!DOCTYPE html>
<html>
    <head>
        <meta http-equiv="Content-type" content="text/html; charset=utf-8"/>
        <title>Experiment</title>
    </head>
    <body>
        <div id="content">
            <!-- this is where the root react component will get rendered -->
        </div>

        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react.js"></script>
        <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/react/15.3.2/react-dom.js"></script>

        <!-- include the webpack-dev-server script so our scripts get reloaded when we make a change -->
        <!-- we'll run the webpack dev server on port 8090, so make sure it is correct -->
        <script src="http://localhost:8090/webpack-dev-server.js"></script>
        <!-- include the bundle that contains all our scripts, produced by webpack -->
        <!-- the bundle is served by the webpack-dev-server, so serve it also from localhost:8090 -->
        <script type="text/javascript" src="http://localhost:8090/assets/main.js"></script>

    </body>
</html>

index.jsx

import {Router, Route, useRouterHistory, browserHistory} from 'react-router';

ReactDOM.render(
  <h1>hello</h1>, document.getElementById('content')
);

webpack.config.js

var webpack = require('webpack');
var merge = require('webpack-merge');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var NpmInstallPlugin = require('npm-install-webpack-plugin');

const TARGET = process.env.npm_lifecycle_event;
console.log("target event is " + TARGET);

var common = {
  cache: true,
  debug: true,
  entry: './src/script/index.jsx',
  resolve: {
    extensions: ['', '.js', '.jsx']
  },
  externals: {
    // Adapt React to different environments.
    'react': {
      commonjs: 'react',
      commonjs2: 'react',
      amd: 'React',
      root: 'React'
    }
  },
  output: {
    filename: '[name].js',
    sourceMapFilename: '[file].map'
  },
  module: {
    loaders: [{
      test: /\.js[x]?$/,
      loaders: ['babel-loader?presets[]=es2015&presets[]=react'],
      exclude: /(node_modules)/
    }, {
      test: /\.css$/,
      loaders: ['style', 'css']
    }, {
      test: /\.scss$/,
      loaders: ['style', 'css', 'sass']
    }, {
      test: /\.less$/,
      loaders: ['style', 'css', 'less']
    }, {
      test: /\.woff$/,
      loader: "url-loader?limit=10000&mimetype=application/font-woff&name=[path][name].[ext]"
    }, {
      test: /\.woff2$/,
      loader: "url-loader?limit=10000&mimetype=application/font-woff2&name=[path][name].[ext]"
    }, {
      test: /\.(eot|ttf|svg|gif|png)$/,
      loader: "file-loader"
    }]
  },
  plugins: [
    new webpack.ProvidePlugin({
      $: "jquery",
      jQuery: "jquery"
    })
  ]
};

if(TARGET === 'dev' || !TARGET) {
    module.exports = merge(common,{
        devtool: 'eval-source-map',
        devServer: {
            historyApiFallback: false
        },
        entry: './src/script/index.jsx',
        output: {
            filename: '[name].js',
            publicPath: 'http://localhost:8090/assets'
        },
        plugins: [
            new NpmInstallPlugin({
                save: true // --save
            }),
            new webpack.DefinePlugin({
                'process.env.NODE_ENV': JSON.stringify('dev')
            })
        ]
    });
}

if (TARGET === 'build') {
  module.exports = merge(common, {
    devtool: 'source-map',
    output: {
      path: './dist'
    }
  });
}

的package.json

"dependencies": {
    "babel": "^6.5.2",
    "babel-core": "^6.18.0",
    "babel-loader": "^6.2.7",
    "babel-preset-es2015": "^6.18.0",
    "babel-preset-react": "^6.16.0",
    "bootstrap": "^3.3.7",
    "css-loader": "^0.25.0",
    "file-loader": "^0.9.0",
    "history": "^2.0.1",
    "html-webpack-plugin": "^2.24.1",
    "http-server": "^0.9.0",
    "jquery": "^3.1.1",
    "less": "^2.7.1",
    "less-loader": "^2.2.3",
    "node-sass": "^3.10.1",
    "npm-install-webpack-plugin": "^4.0.4",
    "react": "^15.3.2",
    "react-datagrid": "^2.1.1",
    "react-dom": "^15.3.2",
    "react-router": "^3.0.0",
    "sass-loader": "^4.0.2",
    "style-loader": "^0.13.1",
    "url-loader": "^0.5.7",
    "webpack": "^1.13.3",
    "webpack-dev-server": "^1.16.2",
    "webpack-merge": "^0.15.0"
  }

1 个答案:

答案 0 :(得分:3)

你能在externals中实际指定环境吗? The docs关于如何使用它似乎非常简单。这是我外部的外观,我使用CDN的React / ReactDOM和其他库没问题:

externals: {
  react: 'React',
  'react-dom': 'ReactDOM'
}

似乎设置了使用output.libraryoutput.libraryTarget选项所需的环境,特别是文档示例中显示的libraryTarget选项。