├── .babelrc
├── .gitignore
├── README.md
├── package.json
├── public
├── assets
│ └── favicon.ico
└── index.html
├── src
├── components
│ └── WebMap.js
├── config.js
├── css
│ ├── index.scss
│ └── main.scss
├── data
│ └── app.js
└── index.js
└── webpack.config.js
/.babelrc:
--------------------------------------------------------------------------------
1 | {
2 | "presets": [
3 | ["@babel/preset-env", {
4 | "useBuiltIns": "entry",
5 | "targets": "> 0.25%, not ie 11, not dead, not op_mini all",
6 | "modules":"amd"
7 | }],
8 | "@babel/preset-react"
9 | ],
10 | "plugins": [
11 | "@babel/proposal-class-properties",
12 | "@babel/proposal-object-rest-spread",
13 | "@babel/plugin-syntax-dynamic-import"
14 | ]
15 | }
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules/*
2 | .vscode/*
3 | build/*
4 | dist/*
5 | html-report/*
6 | ~tmp/*
7 | .baseDir*
8 | .tsdrc
9 | .tscache
10 | npm-debug.log
11 | yarn.lock
12 | package-lock.json
13 | coverage-final.*
14 | .firebaserc
15 | firebase.json
16 | firebase-debug.log
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ArcGIS API for JavaScript with React
2 |
3 | This is a sample application of using the [ArcGIS API for JavaScript](https://developers.arcgis.com/javascript/) with [React](https://reactjs.org/).
4 |
5 | ## Build
6 |
7 | `npm run build`
8 |
9 | ## Development
10 |
11 | `npm start`
12 |
13 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "jsapi-react",
3 | "version": "1.0.0",
4 | "description": "Sample application using the ArcGIS API for JavaScript with React",
5 | "main": "src/index.js",
6 | "scripts": {
7 | "start": "webpack-dev-server --history-api-fallback --mode development --open",
8 | "build": "webpack --mode production",
9 | "serve": "webpack-dev-server --history-api-fallback --mode production --open --https --compress"
10 | },
11 | "keywords": [
12 | "react",
13 | "arcgis",
14 | "gis",
15 | "geodev",
16 | "spatial"
17 | ],
18 | "author": "",
19 | "license": "Apache-2.0",
20 | "dependencies": {
21 | "@arcgis/webpack-plugin": "~4.10.5",
22 | "react": "^16.8.2",
23 | "react-dom": "^16.8.2",
24 | "styled-components": "^4.1.1"
25 | },
26 | "devDependencies": {
27 | "@babel/core": "^7.1.6",
28 | "@babel/plugin-proposal-class-properties": "^7.1.0",
29 | "@babel/plugin-proposal-object-rest-spread": "^7.0.0",
30 | "@babel/plugin-syntax-dynamic-import": "^7.0.0",
31 | "@babel/preset-env": "^7.1.6",
32 | "@babel/preset-react": "^7.0.0",
33 | "@types/arcgis-js-api": "~4.10.0",
34 | "@types/react": "^16.8.2",
35 | "@types/react-dom": "^16.0.7",
36 | "@types/styled-components": "^4.1.0",
37 | "babel-loader": "^8.0.4",
38 | "babel-plugin-styled-components": "^1.8.0",
39 | "clean-webpack-plugin": "^0.1.19",
40 | "copy-webpack-plugin": "^4.6.0",
41 | "css-loader": "^0.28.11",
42 | "html-loader": "^0.5.5",
43 | "html-webpack-inline-source-plugin": "^0.0.10",
44 | "html-webpack-plugin": "^3.1.0",
45 | "mini-css-extract-plugin": "^0.4.0",
46 | "node-sass": "~4.9.4 ",
47 | "optimize-css-assets-webpack-plugin": "^4.0.1",
48 | "prettier": "^1.15.2",
49 | "resolve-url-loader": "^2.3.0",
50 | "sass-loader": "^6.0.7",
51 | "style-loader": "0.20.3",
52 | "ts-jest": "^23.10.4",
53 | "uglifyjs-webpack-plugin": "^1.2.5",
54 | "webpack": "^4.25.1",
55 | "webpack-cli": "^3.1.1",
56 | "webpack-dev-server": "^3.1.10"
57 | }
58 | }
59 |
--------------------------------------------------------------------------------
/public/assets/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/odoe/jsapi-react/dcb6376e81af64f051c83a8d0062f82c8a8efcf6/public/assets/favicon.ico
--------------------------------------------------------------------------------
/public/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 | ArcGIS React Sample
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/src/components/WebMap.js:
--------------------------------------------------------------------------------
1 | import React, { useEffect, useRef } from "react";
2 |
3 | export function WebMap() {
4 | const elementRef = useRef();
5 |
6 | useEffect(_ => {
7 | let cleanup;
8 | // lazy load the module that loads the JSAPI
9 | // and initialize it
10 | import("../data/app").then(
11 | app => cleanup = app.initialize(elementRef.current)
12 | );
13 | return () => cleanup && cleanup();
14 | }, []);
15 |
16 | // assign elementRef to the ref of our component
17 | return (
18 |
19 |
20 | );
21 | }
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/src/config.js:
--------------------------------------------------------------------------------
1 | import "@dojo/framework/shim/Promise";
2 | import esriConfig from "esri/config";
3 |
4 | const DEFAULT_WORKER_URL = "https://js.arcgis.com/4.10/";
5 | const DEFAULT_LOADER_URL = `${DEFAULT_WORKER_URL}dojo/dojo-lite.js`;
6 |
7 | esriConfig.workers.loaderUrl = DEFAULT_LOADER_URL;
8 | esriConfig.workers.loaderConfig = {
9 | baseUrl: `${DEFAULT_WORKER_URL}dojo`,
10 | packages: [
11 | { name: "esri", location: DEFAULT_WORKER_URL + "esri" },
12 | { name: "dojo", location: DEFAULT_WORKER_URL + "dojo" },
13 | { name: "dojox", location: DEFAULT_WORKER_URL + "dojox" },
14 | { name: "dijit", location: DEFAULT_WORKER_URL + "dijit" },
15 | { name: "dstore", location: DEFAULT_WORKER_URL + "dstore" },
16 | { name: "moment", location: DEFAULT_WORKER_URL + "moment" },
17 | { name: "@dojo", location: DEFAULT_WORKER_URL + "@dojo" },
18 | {
19 | name: "cldrjs",
20 | location: DEFAULT_WORKER_URL + "cldrjs",
21 | main: "dist/cldr"
22 | },
23 | {
24 | name: "globalize",
25 | location: DEFAULT_WORKER_URL + "globalize",
26 | main: "dist/globalize"
27 | },
28 | {
29 | name: "maquette",
30 | location: DEFAULT_WORKER_URL + "maquette",
31 | main: "dist/maquette.umd"
32 | },
33 | {
34 | name: "maquette-css-transitions",
35 | location: DEFAULT_WORKER_URL + "maquette-css-transitions",
36 | main: "dist/maquette-css-transitions.umd"
37 | },
38 | {
39 | name: "maquette-jsx",
40 | location: DEFAULT_WORKER_URL + "maquette-jsx",
41 | main: "dist/maquette-jsx.umd"
42 | },
43 | { name: "tslib", location: DEFAULT_WORKER_URL + "tslib", main: "tslib" }
44 | ]
45 | };
--------------------------------------------------------------------------------
/src/css/index.scss:
--------------------------------------------------------------------------------
1 | html,
2 | body {
3 | padding: 0;
4 | margin: 0;
5 | width: 100%;
6 | height: 100%;
7 | font-feature-settings: "liga" 1, "calt" 0;
8 | }
9 |
10 | #root, .viewDiv {
11 | padding: 0;
12 | margin: 0;
13 | width: 100%;
14 | height: 100%;
15 | display: flex;
16 | letter-spacing: 0em;
17 | line-height: 1.55rem;
18 | }
19 |
--------------------------------------------------------------------------------
/src/css/main.scss:
--------------------------------------------------------------------------------
1 | $image-path: "~calcite-web/dist/img" !default;
2 | $font-path: "~calcite-web/dist/fonts" !default;
3 |
4 | $icomoon-font-path: "~arcgis-js-api/themes/base/icons/fonts" !default;
5 |
6 | // Widgets (sorted alphabetically)
7 | $include_AreaMeasurement3D: false !default;
8 | $include_Attribution: true !default;
9 | $include_BasemapGallery: false !default;
10 | $include_BasemapToggle: false !default;
11 | $include_Bookmarks: false !default;
12 | $include_BrowseItems: false !default;
13 | $include_ColorPicker: false !default;
14 | $include_Compass: true !default;
15 | $include_CoordinateConversion: false !default;
16 | $include_DatePicker: false !default;
17 | $include_Directions: false !default;
18 | $include_Expand: false !default;
19 | $include_Feature: false !default;
20 | $include_FeatureForm: false !default;
21 | $include_HorizontalSlider: false !default;
22 | $include_LayerList: false !default;
23 | $include_Legend: false !default;
24 | $include_NavigationToggle: false !default;
25 | $include_Print: false !default;
26 | $include_DirectLineMeasurement3D: false !default;
27 | $include_Popup: true !default;
28 | $include_RasterSymbologyEditor: false !default;
29 | $include_RendererSlider: false !default;
30 | $include_ScaleBar: false !default;
31 | $include_Search: true !default;
32 | $include_Slice: false !default;
33 | $include_Spinner: true !default;
34 | $include_Tags: false !default;
35 | $include_FeatureTemplates: false !default;
36 | $include_TimePicker: false !default;
37 | $include_Zoom: true !default;
38 |
39 | @import "~arcgis-js-api/themes/light/main.scss";
40 | @import "index";
--------------------------------------------------------------------------------
/src/data/app.js:
--------------------------------------------------------------------------------
1 | import WebMap from "esri/WebMap";
2 | import MapView from "esri/views/MapView";
3 | import Search from "esri/widgets/Search";
4 |
5 | const noop = () => {};
6 |
7 | export const webmap = new WebMap({
8 | portalItem: {
9 | id: "974c6641665a42bf8a57da08e607bb6f"
10 | }
11 | });
12 |
13 | export const view = new MapView({
14 | map: webmap
15 | });
16 |
17 | export const search = new Search({ view });
18 | view.ui.add(search, "top-right");
19 |
20 | export const initialize = (container) => {
21 | view.container = container;
22 | view
23 | .when()
24 | .then(_ => {
25 | console.log("Map and View are ready");
26 | })
27 | .catch(noop);
28 | return () => {
29 | view.container = null;
30 | };
31 | };
32 |
33 |
--------------------------------------------------------------------------------
/src/index.js:
--------------------------------------------------------------------------------
1 | import "./config";
2 |
3 | import React from "react";
4 | import { render } from "react-dom";
5 |
6 | import { WebMap } from "./components/WebMap";
7 |
8 | const rootElement = document.getElementById("root");
9 | render(, rootElement);
10 |
11 |
--------------------------------------------------------------------------------
/webpack.config.js:
--------------------------------------------------------------------------------
1 | const ArcGISPlugin = require("@arcgis/webpack-plugin");
2 | const CleanWebpackPlugin = require("clean-webpack-plugin");
3 | const HtmlWebPackPlugin = require("html-webpack-plugin");
4 | const HtmlWebpackInlineSourcePlugin = require("html-webpack-inline-source-plugin");
5 | const MiniCssExtractPlugin = require("mini-css-extract-plugin");
6 | const OptimizeCSSAssetsPlugin = require("optimize-css-assets-webpack-plugin");
7 | const UglifyJsPlugin = require("uglifyjs-webpack-plugin");
8 |
9 | const path = require("path");
10 | const webpack = require("webpack");
11 |
12 | module.exports = function(_, arg) {
13 | const config = {
14 | entry: {
15 | index: ["./src/css/main.scss", "./src/index.js"]
16 | },
17 | output: {
18 | filename: "[name].[chunkhash].js",
19 | publicPath: ""
20 | },
21 | optimization: {
22 | minimizer: [
23 | new UglifyJsPlugin({
24 | uglifyOptions: {
25 | output: {
26 | comments: false
27 | }
28 | },
29 | cache: true,
30 | parallel: true,
31 | sourceMap: false
32 | }),
33 | new OptimizeCSSAssetsPlugin({
34 | cssProcessorOptions: {
35 | discardComments: {
36 | removeAll: true
37 | },
38 | // Run cssnano in safe mode to avoid
39 | // potentially unsafe transformations.
40 | safe: true
41 | }
42 | })
43 | ]
44 | },
45 | module: {
46 | rules: [
47 | {
48 | exclude: /node_modules/,
49 | test: /\.js?$/,
50 | loader: "babel-loader"
51 | },
52 | {
53 | test: /\.html$/,
54 | use: [
55 | {
56 | loader: "html-loader",
57 | options: { minimize: false }
58 | }
59 | ],
60 | exclude: /node_modules/
61 | },
62 | {
63 | test: /\.(jpe?g|png|gif|svg|webp)$/,
64 | loader: "url-loader",
65 | options: {
66 | // Inline files smaller than 10 kB (10240 bytes)
67 | limit: 10 * 1024
68 | }
69 | },
70 | {
71 | test: /\.(wsv|ttf|otf|eot|woff(2)?)(\?[a-z0-9]+)?$/,
72 | use: [
73 | {
74 | loader: "file-loader",
75 | options: {
76 | name: "build/[name].[ext]"
77 | }
78 | }
79 | ]
80 | },
81 | {
82 | test: /\.css$|\.scss$/,
83 | use: [
84 | MiniCssExtractPlugin.loader,
85 | "css-loader",
86 | {
87 | loader: "resolve-url-loader",
88 | options: { includeRoot: true }
89 | },
90 | {
91 | loader: "sass-loader",
92 | options: {
93 | sourceMap: true,
94 | includePaths: [
95 | path.resolve("./node_modules")
96 | ]
97 | }
98 | }
99 | ]
100 | }
101 | ]
102 | },
103 | plugins: [
104 | new webpack.DefinePlugin({
105 | "process.env.NODE_ENV": JSON.stringify(arg.mode || "production")
106 | }),
107 |
108 | new CleanWebpackPlugin(["dist"]),
109 |
110 | new ArcGISPlugin({
111 | useDefaultAssetLoaders: false
112 | }),
113 |
114 | new HtmlWebPackPlugin({
115 | template: "./public/index.html",
116 | filename: "./index.html",
117 | favicon: "./public/assets/favicon.ico",
118 | chunksSortMode: "none",
119 | inlineSource: ".(css)$",
120 | mode: arg.mode
121 | }),
122 |
123 | new MiniCssExtractPlugin({
124 | filename: "[name].[chunkhash].css",
125 | chunkFilename: "[id].css"
126 | }),
127 |
128 | new HtmlWebpackInlineSourcePlugin()
129 | ],
130 | resolve: {
131 | modules: [
132 | path.resolve(__dirname, "/src"),
133 | path.resolve(__dirname, "node_modules/")
134 | ],
135 | extensions: [".js", ".scss", ".css"]
136 | },
137 | node: {
138 | process: false,
139 | global: false,
140 | fs: "empty"
141 | }
142 | };
143 |
144 | return config;
145 | };
146 |
--------------------------------------------------------------------------------