Search code examples
javascriptreactjswebpackjsxcesiumjs

Integrating Cesium/Resium with a build of npx create-react-app is not working


I'm using an "ejected" version of npx create-react-app due to my needing to add several dependencies. This has all working just fine until I need to add Cesium and Resium.

I've been following these instructions for configuring webpack, but I'm assuming there is something about the configuration that comes with "npx create-react-app" that is making the requirements slightly different.

https://resium.darwineducation.com/installation2

I've also tried craco-cesium, as instructed, but it doesn't seem to work neither - I get the same message.

So as most of you know, the webpack that comes along with the npx package for React is quite large. So I think this is where the issue lies. I've added the following to the default webpack.config.js

const cesiumSource = "../node_modules/cesium/Source"
const cesiumWorkers = "../Build/Cesium/Workers"

{
...
alias: {
    'react-native': 'react-native-web',
     cesium$: 'cesium/Cesium',
     cesium: 'cesium/Source'
},
...
plugins: [
     new CopyWebpackPlugin([
        {
          from: path.join(cesiumSource, cesiumWorkers),
          to: "Workers",
        },
        {
          from: path.join(cesiumSource, "Assets"),
          to: "Assets",
        },
        {
          from: path.join(cesiumSource, "Widgets"),
          to: "Widgets",
        },
     ]),
      new webpack.DefinePlugin(env.stringified),
      new webpack.DefinePlugin({
        CESIUM_BASE_URL: JSON.stringify("/"),
      }),
]
...
}

I'm getting the errors:

unable to locate '..\node_modules\cesium\Build\Cesium\Workers' at 'C:\Users\USER\Documents\viper-noms\node_modules\cesium\Build\Cesium\Workers'

unable to locate '..\node_modules\cesium\Source\Assets' at 'C:\Users\USER\Documents\viper-noms\node_modules\cesium\Source\Assets'

unable to locate '..\node_modules\cesium\Source\Widgets' at 'C:\Users\USER\Documents\viper-noms\node_modules\cesium\Source\Widgets'

Which make me think that the issue is something to do with the new webpack.DefinePlugin()

Any ideas? I'm pretty sure create-react-app changes the publicPath, but I'm not clear on how to accommodate for it.


Solution

  • I was unable to troubleshoot the npx create-react-app build. But I was able to step through the installation of modules manually and got it to work. For those of you that need this sort of thing, here are the config files for a stable build using React + Redux + Cesium + TypeScript.

    If anyone has more insight into why I had issues please feel free to chime in. I'll switch the answer if someone can point out a way to get the create-react-app working.

    package.JSON:

    {
      "name": "project",
      "version": "0.0.1",
      "private": true,
      "scripts": {
        "bundle": "webpack",
        "type-check": "tsc --noEmit",
        "type-check:watch": "npm run type-check -- --watch",
        "start": "webpack-dev-server",
        "test": "eslint .",
        "build": "webpack --mode production"
      },
      "devDependencies": {
        "@babel/core": "7.5.5",
        "@babel/plugin-proposal-class-properties": "7.5.5",
        "@babel/plugin-proposal-object-rest-spread": "7.5.5",
        "@babel/preset-env": "7.5.5",
        "@babel/preset-react": "7.0.0",
        "@babel/preset-typescript": "7.3.3",
        "babel-loader": "8.0.6",
        "copy-webpack-plugin": "^5.0.3",
        "css-loader": "^3.1.0",
        "eslint": "^6.0.1",
        "eslint-plugin-react": "^7.14.3",
        "html-webpack-include-assets-plugin": "^2.0.0",
        "html-webpack-plugin": "^3.2.0",
        "strip-pragma-loader": "^1.0.0",
        "style-loader": "^0.23.1",
        "typescript": "^3.3.3",
        "url-loader": "^2.0.1",
        "webpack": "^4.37.0",
        "webpack-cli": "^3.3.6",
        "webpack-dev-server": "^3.7.2"
      },
      "dependencies": {
        "@types/cesium": "^1.59.0",
        "@types/node": "^12.7.5",
        "@types/react": "^16.9.2",
        "@types/react-dom": "^16.9.0",
        "cesium": "^1.59.0",
        "react": "^16.8.6",
        "react-dom": "^16.8.6",
        "redux": "^4.0.4",
        "resium": "^1.7.0",
        "source-map-loader": "^0.2.4",
        "typescript": "^3.6.3"
      }
    }
    

    webpack.config.js

    "use strict";
    
    const path = require("path");
    
    const webpack = require("webpack");
    const HtmlPlugin = require("html-webpack-plugin");
    const CopyPlugin = require("copy-webpack-plugin");
    
    const cesiumSource = "node_modules/cesium/Source";
    const cesiumWorkers = "../Build/Cesium/Workers";
    
    module.exports = (env, args) => {
      const prod = args.mode === "production";
      return {
        context: __dirname,
        devServer: {
          hot: true,
          port: 3000,
          open: true,
        },
        devtool: !prod ? void 0 : "eval-source-map",
        entry: ["./src/index.js"],
        output: {
          filename: '[name].js',
          path: path.join(__dirname, "./build"),
          sourcePrefix: "",
        },
        resolve: {
          alias: {
            cesium$: "cesium/Cesium",
            cesium: "cesium/Source"
          },
          extensions: [".ts", ".tsx", ".js", ".jsx"]
        },
        mode: prod ? "production" : "development",
        module: {
          rules: [
            {
              test: /\.(ts|js)x?$/,
              exclude: /node_modules/,
              loader: 'babel-loader',
            },
            {
              test: /\.css$/,
              use: ["style-loader", "css-loader"],
            },
            {
              test: /\.(png|gif|jpg|jpeg|svg|xml|json)$/,
              use: ["url-loader"],
            },
            { 
              enforce: "pre", 
              test: /\.js$/, 
              loader: "source-map-loader" 
            },
            ...[
              prod
                ? {
                    // Strip cesium pragmas
                    test: /\.js$/,
                    enforce: "pre",
                    include: path.resolve(__dirname, cesiumSource),
                    use: [
                      {
                        loader: "strip-pragma-loader",
                        options: {
                          pragmas: {
                            debug: false,
                          },
                        },
                      },
                    ],
                  }
                : {},
            ],
          ],
        },
        amd: {
          toUrlUndefined: true,
        },
        node: {
          fs: "empty",
        },
        plugins: [
          new webpack.DefinePlugin({
            CESIUM_BASE_URL: JSON.stringify("/"),
          }),
          new CopyPlugin([
            {
              from: path.join(cesiumSource, cesiumWorkers),
              to: "Workers",
            },
            {
              from: path.join(cesiumSource, "Assets"),
              to: "Assets",
            },
            {
              from: path.join(cesiumSource, "Widgets"),
              to: "Widgets",
            },
          ]),
          new HtmlPlugin({ inject: true, template: path.join(path.resolve(__dirname, ''), 'index.html') }),
          ...(prod ? [] : [new webpack.HotModuleReplacementPlugin()]),
        ],
      };
    };
    

    tsconfig.json

    {
      "compilerOptions": {
        "allowSyntheticDefaultImports": true,
        "noFallthroughCasesInSwitch": true,
        "noUnusedParameters": true,
        "noImplicitReturns": true,
        "moduleResolution": "node",
        "esModuleInterop": true,
        "noUnusedLocals": true,
        "noImplicitAny": true,
        "target": "es2015",
        "module": "es2015",
        "strict": true,
        "jsx": "react"
      },
      "include": [
        "src/**/*"
      ],
      "exclude": [
        "node_modules",
        "dist"
      ]
    }
    

    .babelrc

    {
      "presets": [
        "@babel/env",
        "@babel/typescript",
        "@babel/react"
      ],
      "plugins": [
        "@babel/proposal-class-properties",
        "@babel/proposal-object-rest-spread"
      ]
    }