浏览代码

Basic Electron App setup (#2765)

* Basic Electron setup.

* wip

* Integrate electron with react components from apps workspace

* Refactor package.json scripts.

* Copy public files from apps.

* Import 'initSettings' from apps workspace, fix code style, move scripts into global package.json

* Add build electron step into CI

* Split webpack file into renderer and main

* Add HMR into renderer.config

* Add optimization process in main webpack configuration

* Add ts translation in main webpack config and fix electron start script

* Update dependencies.

* Update dependencies. Change package name.

* Move initSettings func into Api component

* Extract webpack base config and move initSettings into react-api

* Fix webpack config and simplify initSettings import

* WIP on packing electron app (electron.ts doesnt have relative path)

* Fix relative path to the main index.html

* Add README in electron package, update main package.json scripts, add mention about electron-package in main README

* Remove unused dependencies form electron package.json

* Missing file from merge

* Fix main README and change name field in main package.json

* Update dependencies.

* Remove old webpack-dev-serve (creating issues with plugin)

Co-authored-by: jozwiak <kubencki@gmail.com>
Co-authored-by: Jaco Greeff <jacogr@gmail.com>
Krzysztof Jelski 4 年之前
父节点
当前提交
e38b27ad90

+ 1 - 0
README.md

@@ -17,6 +17,7 @@ This can be accessed as a hosted application via [https://polkadot.js.org/apps/]
 The repo is split into a number of packages, each representing an application. These are -
 
 - [apps](packages/apps/) This is the main entry point. It handles the selection sidebar and routing to the specific application being displayed.
+- [apps-electron](packages/apps-electron/) Desktop app running [apps](packages/apps/).
 - [page-accounts](packages/page-accounts/) A basic account management app.
 - [page-address-book](packages/page-address-book/) A basic address management app.
 - [page-democracy](packages/page-democracy/) A basic voting app, allowing votes on activate proposals and referenda.

+ 38 - 2
package.json

@@ -1,12 +1,29 @@
 {
+  "name": "polkadot-apps",
   "repository": "https://github.com/polkadot-js/apps",
+  "main": "packages/apps-electron/build/electron.js",
+  "description": "An Apps portal into the Polkadot network",
   "author": "Jaco Greeff <jacogr@gmail.com>",
+  "version": "0.42.0-beta.147",
   "license": "Apache-2",
   "private": true,
   "homepage": ".",
   "workspaces": [
     "packages/*"
   ],
+  "build": {
+    "productName": "Polkadot",
+    "files": [
+      "./packages/apps-electron/build"
+    ],
+    "appId": "com.polkadot.polkadot-app",
+    "mac": {
+      "category": "public.app-category.finance"
+    },
+    "directories": {
+      "output": "./packages/apps-electron/release"
+    }
+  },
   "resolutions": {
     "@polkadot/api": "^1.15.0-beta.5",
     "@polkadot/api-contract": "^1.15.0-beta.5",
@@ -20,22 +37,36 @@
     "analyze": "yarn run build && cd packages/apps && yarn run source-map-explorer build/main.*.js",
     "build": "yarn run build:i18n && yarn run build:code",
     "build:code": "NODE_ENV=production node_modules/@polkadot/dev/scripts/polkadot-dev-build-ts.js",
-    "build:electron": "echo \"Dummy\"",
     "build:i18n": "i18next-scanner --config i18next-scanner.config.js && node ./scripts/i18nSort.js",
     "build:release:electron": "echo \"Dummy\"",
     "build:release:ipfs": "node scripts/ipfsUpload.js",
     "build:release:ghpages": "yarn polkadot-ci-ghact-docs",
     "build:release:www": "yarn polkadot-ci-ghact-build && yarn build:release:ipfs && yarn build:release:ghpages",
     "build:www": "rm -rf packages/apps/build && mkdir -p packages/apps/build && yarn run build:i18n && cd packages/apps && NODE_ENV=production webpack --config webpack.config.js",
+    "build:electron": "yarn clean:electronBuild && yarn build:electronMain && yarn build:electronRenderer",
+    "build:devElectronRenderer": "cd packages/apps-electron && webpack-dev-server --color --progress --config webpack.renderer.config.js",
+    "build:electronRenderer": "cd packages/apps-electron && NODE_ENV=production webpack --config webpack.renderer.config.js",
+    "build:devElectronMain": "cd packages/apps-electron && webpack --config webpack.main.config.js",
+    "build:electronMain": "cd packages/apps-electron && NODE_ENV=production webpack --config webpack.main.config.js",
+    "prepackElectron": "yarn build:electron && yarn postinstall:electron",
+    "packElectron:test": "yarn prepackElectron && electron-builder --dir",
+    "packElectron:mac": "yarn prepackElectron && electron-builder build --mac",
+    "packElectron:win": "yarn prepackElectron && electron-builder build --win",
+    "packElectron:linux": "yarn prepackElectron && electron-builder build --linux",
+    "packElectron": "yarn prepackElectron && yarn clean:electronRelease && electron-builder build --linux --win --mac",
     "docs": "echo \"skipping docs\"",
     "clean": "polkadot-dev-clean-build",
+    "clean:electronBuild": "cd packages/apps-electron polkadot-dev-clean-build",
+    "clean:electronRelease": "cd packages/apps-electron && rm -rf release",
     "clean:i18n": "rm -rf packages/apps/public/locales/en && mkdir -p packages/apps/public/locales/en",
     "lint": "polkadot-dev-run-lint",
     "lint:css": "stylelint './packages/**/src/**/*.tsx'",
     "postinstall": "polkadot-dev-yarn-only",
+    "postinstall:electron": "electron-builder install-app-deps",
     "test": "polkadot-dev-run-test packages/page-claims/src",
     "test:one": "polkadot-dev-run-test",
-    "start": "yarn clean && cd packages/apps && webpack --config webpack.config.js"
+    "start": "yarn clean && cd packages/apps && webpack --config webpack.config.js",
+    "start:electron": "yarn clean:electronBuild && concurrently 'yarn build:devElectronMain && cd packages/apps-electron && electron ./build/electron.js' 'yarn build:devElectronRenderer'"
   },
   "devDependencies": {
     "@babel/core": "^7.9.6",
@@ -57,14 +88,19 @@
     "@types/store": "^2.0.2",
     "@types/styled-components": "^5.1.0",
     "@types/styled-theming": "^2.2.2",
+    "concurrently": "^5.2.0",
+    "electron": "8.2.3",
+    "electron-builder": "^22.6.1",
     "i18next-scanner": "^2.11.0",
     "react": "^16.13.1",
     "react-dom": "^16.13.1",
     "stylelint": "^13.3.3",
     "stylelint-config-recommended": "^3.0.0",
     "stylelint-config-styled-components": "^0.1.1",
+    "terser-webpack-plugin": "^3.0.1",
     "webpack": "^4.43.0",
     "webpack-cli": "^3.3.11",
+    "webpack-merge": "^4.2.2",
     "webpack-plugin-serve": "^1.0.0"
   }
 }

+ 3 - 0
packages/apps-electron/.gitignore

@@ -0,0 +1,3 @@
+build
+node_modules
+release

+ 3 - 0
packages/apps-electron/README.md

@@ -0,0 +1,3 @@
+# @polkadot/apps-electron
+
+WARNING: This is not deemed stable yet for external use.

+ 22 - 0
packages/apps-electron/package.json

@@ -0,0 +1,22 @@
+{
+  "name": "@polkadot/apps-electron",
+  "main": "index.js",
+  "private": true,
+  "version": "0.42.0-beta.147",
+  "dependencies": {
+    "@babel/polyfill": "^7.8.7",
+    "@polkadot/dev": "^0.52.15",
+    "@polkadot/react-components": "0.42.0-beta.147"
+  },
+  "devDependencies": {
+    "@types/react": "^16.9.35",
+    "@types/react-dom": "^16.9.8",
+    "babel-loader": "^8.1.0",
+    "copy-webpack-plugin": "^5.1.1",
+    "html-webpack-plugin": "^4.3.0",
+    "react": "^16.13.1",
+    "react-dom": "^16.13.1",
+    "thread-loader": "^2.1.3",
+    "webpack": "^4.43.0"
+  }
+}

+ 30 - 0
packages/apps-electron/src/electron.ts

@@ -0,0 +1,30 @@
+// Copyright 2017-2020 @polkadot/apps authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import { BrowserWindow, app } from 'electron';
+import path from 'path';
+
+const environment = process.env.NODE_ENV || 'production';
+
+function createWindow (): void {
+  // Create the browser window.
+  const win = new BrowserWindow({
+    height: 600,
+    webPreferences: {
+      nodeIntegration: true
+    },
+    width: 800
+  });
+
+  if (environment === 'development') {
+    win.loadURL('http://0.0.0.0:9000/');
+    win.webContents.openDevTools();
+  } else {
+    const mainFilePath = path.resolve(__dirname, 'index.html');
+
+    win.loadFile(mainFilePath);
+  }
+}
+
+app.whenReady().then(createWindow);

+ 50 - 0
packages/apps-electron/src/index.tsx

@@ -0,0 +1,50 @@
+// Copyright 2017-2020 @polkadot/apps authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+import React, { Suspense } from 'react';
+import ReactDOM from 'react-dom';
+import { HashRouter } from 'react-router-dom';
+
+// setup these right at front
+import 'semantic-ui-css/semantic.min.css';
+import '@polkadot/react-components/i18n';
+
+import { ThemeProvider } from 'styled-components';
+import settings from '@polkadot/ui-settings';
+import Queue from '@polkadot/react-components/Status/Queue';
+import { BlockAuthors, Events } from '@polkadot/react-query';
+import AccountSidebar from '@polkadot/app-accounts/Sidebar';
+import { Api } from '@polkadot/react-api';
+import Apps from '@polkadot/apps/Apps';
+
+const rootId = 'root';
+const rootElement = document.getElementById(rootId);
+const theme = { theme: settings.uiTheme };
+
+if (!rootElement) {
+  throw new Error(`Unable to find element with id '${rootId}'`);
+}
+
+console.log('Opened in electron app');
+
+ReactDOM.render(
+  <Suspense fallback='...'>
+    <ThemeProvider theme={theme}>
+      <Queue>
+        <Api url={settings.apiUrl}>
+          <BlockAuthors>
+            <Events>
+              <AccountSidebar>
+                <HashRouter>
+                  <Apps />
+                </HashRouter>
+              </AccountSidebar>
+            </Events>
+          </BlockAuthors>
+        </Api>
+      </Queue>
+    </ThemeProvider>
+  </Suspense>,
+  rootElement
+);

+ 48 - 0
packages/apps-electron/webpack.main.config.js

@@ -0,0 +1,48 @@
+// Copyright 2017-2020 @polkadot/apps authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+/* eslint-disable @typescript-eslint/camelcase */
+
+const TerserPlugin = require('terser-webpack-plugin');
+const path = require('path');
+const ENV = process.env.NODE_ENV || 'development';
+const isProd = ENV === 'production';
+
+function createWebpack () {
+  return [
+    {
+      entry: './src/electron.ts',
+      mode: ENV,
+      module: {
+        rules: [
+          {
+            exclude: /(node_modules)/,
+            test: /\.(js|ts|tsx)$/,
+            use: [
+              require.resolve('thread-loader'),
+              {
+                loader: require.resolve('babel-loader'),
+                options: require('@polkadot/dev/config/babel')
+              }
+            ]
+          }
+        ]
+      },
+      node: {
+        __dirname: false
+      },
+      optimization: {
+        minimize: !!isProd,
+        minimizer: [new TerserPlugin()]
+      },
+      output: {
+        filename: 'electron.js',
+        path: path.join(__dirname, '/build')
+      },
+      target: 'electron-main'
+    }
+  ];
+}
+
+module.exports = createWebpack();

+ 46 - 0
packages/apps-electron/webpack.renderer.config.js

@@ -0,0 +1,46 @@
+// Copyright 2017-2020 @polkadot/apps authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+/* eslint-disable @typescript-eslint/camelcase */
+
+const merge = require('webpack-merge');
+const baseConfig = require('@polkadot/apps/webpack.base.config');
+const path = require('path');
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
+const findPackages = require('../../scripts/findPackages');
+
+const ENV = process.env.NODE_ENV || 'development';
+const isProd = ENV === 'production';
+const context = __dirname;
+
+module.exports = merge(
+  baseConfig({
+    alias: findPackages().reduce((alias, { dir, name }) => {
+      alias[name] = path.resolve(context, `../${dir}/src`);
+
+      return alias;
+    }, {}),
+    context
+  }),
+  {
+    devServer: {
+      compress: true,
+      contentBase: path.join(__dirname, 'build'),
+      hot: true,
+      liveReload: false,
+      port: 9000
+    },
+    devtool: isProd ? 'none' : 'source-map',
+    plugins: [
+      new CopyWebpackPlugin([{ from: '../apps/public' }]),
+      new HtmlWebpackPlugin({
+        PAGE_TITLE: 'Polkadot/Substrate Portal',
+        inject: true,
+        template: path.join(context, '../apps/public/index.html')
+      })
+    ],
+    target: 'electron-renderer'
+  }
+);

+ 1 - 0
packages/apps/public/locales/en/apps-electron.json

@@ -0,0 +1 @@
+{}

+ 0 - 1
packages/apps/src/index.tsx

@@ -3,7 +3,6 @@
 // of the Apache-2.0 license. See the LICENSE file for details.
 
 // setup these right at front
-import './initSettings';
 import 'semantic-ui-css/semantic.min.css';
 import '@polkadot/react-components/i18n';
 

+ 175 - 0
packages/apps/webpack.base.config.js

@@ -0,0 +1,175 @@
+// Copyright 2017-2020 @polkadot/apps authors & contributors
+// This software may be modified and distributed under the terms
+// of the Apache-2.0 license. See the LICENSE file for details.
+
+/* eslint-disable @typescript-eslint/camelcase */
+
+const fs = require('fs');
+const path = require('path');
+const webpack = require('webpack');
+
+const CopyWebpackPlugin = require('copy-webpack-plugin');
+const MiniCssExtractPlugin = require('mini-css-extract-plugin');
+
+const ENV = process.env.NODE_ENV || 'development';
+
+function createWebpack ({ alias = {}, context, name = 'index' }) {
+  const pkgJson = require(path.join(context, 'package.json'));
+  const isProd = ENV === 'production';
+  const hasPublic = fs.existsSync(path.join(context, 'public'));
+  const plugins = hasPublic
+    ? [new CopyWebpackPlugin([{ from: 'public' }])]
+    : [];
+  // disabled, smooths dev load, was -
+  // isProd ? 'source-map' : 'cheap-eval-source-map',
+
+  return {
+    context,
+    entry: [
+      '@babel/polyfill',
+      `./src/${name}.tsx`,
+      isProd
+        ? null
+        : null // 'webpack-plugin-serve/client'
+    ].filter((entry) => entry),
+    mode: ENV,
+    module: {
+      rules: [
+        {
+          exclude: /(node_modules)/,
+          test: /\.css$/,
+          use: [
+            isProd
+              ? MiniCssExtractPlugin.loader
+              : require.resolve('style-loader'),
+            {
+              loader: require.resolve('css-loader'),
+              options: {
+                importLoaders: 1
+              }
+            }
+          ]
+        },
+        {
+          include: /node_modules/,
+          test: /\.css$/,
+          use: [
+            isProd
+              ? MiniCssExtractPlugin.loader
+              : require.resolve('style-loader'),
+            require.resolve('css-loader')
+          ]
+        },
+        {
+          exclude: /(node_modules)/,
+          test: /\.(js|ts|tsx)$/,
+          use: [
+            require.resolve('thread-loader'),
+            {
+              loader: require.resolve('babel-loader'),
+              options: require('@polkadot/dev/config/babel')
+            }
+          ]
+        },
+        {
+          test: /\.md$/,
+          use: [
+            require.resolve('html-loader'),
+            require.resolve('markdown-loader')
+          ]
+        },
+        {
+          test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
+          use: [
+            {
+              loader: require.resolve('url-loader'),
+              options: {
+                esModule: false,
+                limit: 10000,
+                name: 'static/[name].[hash:8].[ext]'
+              }
+            }
+          ]
+        },
+        {
+          test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
+          use: [
+            {
+              loader: require.resolve('file-loader'),
+              options: {
+                esModule: false,
+                name: 'static/[name].[hash:8].[ext]'
+              }
+            }
+          ]
+        }
+      ]
+    },
+    node: {
+      child_process: 'empty',
+      dgram: 'empty',
+      fs: 'empty',
+      net: 'empty',
+      tls: 'empty'
+    },
+    optimization: {
+      runtimeChunk: 'single',
+      splitChunks: {
+        cacheGroups: {
+          polkadotJs: {
+            chunks: 'initial',
+            enforce: true,
+            name: 'polkadotjs',
+            test: /node_modules\/(@polkadot\/wasm-crypto)/
+          },
+          vendorOther: {
+            chunks: 'initial',
+            enforce: true,
+            name: 'vendor',
+            test: /node_modules\/(asn1|bn\.js|buffer|cuint|elliptic|lodash|moment|readable-stream|rxjs)/
+          },
+          vendorReact: {
+            chunks: 'initial',
+            enforce: true,
+            name: 'react',
+            test: /node_modules\/(chart|i18next|react|semantic-ui)/
+          }
+        }
+      }
+    },
+    output: {
+      chunkFilename: '[name].[chunkhash:8].js',
+      filename: '[name].[hash:8].js',
+      globalObject: '(typeof self !== \'undefined\' ? self : this)',
+      path: path.join(context, 'build'),
+      publicPath: ''
+    },
+    performance: {
+      hints: false
+    },
+    plugins: plugins.concat([
+      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
+      new webpack.DefinePlugin({
+        'process.env': {
+          NODE_ENV: JSON.stringify(ENV),
+          VERSION: JSON.stringify(pkgJson.version),
+          WS_URL: JSON.stringify(process.env.WS_URL)
+        }
+      }),
+      new webpack.optimize.SplitChunksPlugin(),
+      new MiniCssExtractPlugin({
+        filename: '[name].[contenthash:8].css'
+      })
+    ]).filter((plugin) => plugin),
+    resolve: {
+      alias,
+      extensions: ['.js', '.jsx', '.ts', '.tsx']
+    },
+    watch: !isProd,
+    watchOptions: {
+      ignored: ['.yarn', /build/, /node_modules/]
+    }
+  };
+}
+
+module.exports = createWebpack;

+ 35 - 185
packages/apps/webpack.config.js

@@ -6,197 +6,47 @@
 
 const fs = require('fs');
 const path = require('path');
-const webpack = require('webpack');
-
-const CopyWebpackPlugin = require('copy-webpack-plugin');
-const MiniCssExtractPlugin = require('mini-css-extract-plugin');
-const HtmlWebpackPlugin = require('html-webpack-plugin');
+const merge = require('webpack-merge');
+const baseConfig = require('./webpack.base.config');
 const { WebpackPluginServe } = require('webpack-plugin-serve');
-
 const findPackages = require('../../scripts/findPackages');
+const HtmlWebpackPlugin = require('html-webpack-plugin');
 
+const devtool = false;
 const ENV = process.env.NODE_ENV || 'development';
-
-function createWebpack ({ alias = {}, context, name = 'index' }) {
-  const pkgJson = require(path.join(context, 'package.json'));
-  const isProd = ENV === 'production';
-  const hasPublic = fs.existsSync(path.join(context, 'public'));
-  const plugins = hasPublic
-    ? [new CopyWebpackPlugin([{ from: 'public' }])]
-    : [];
-  // disabled, smooths dev load, was -
-  // isProd ? 'source-map' : 'cheap-eval-source-map',
-  const devtool = false;
-
-  return {
-    context,
+const isProd = ENV === 'production';
+const context = __dirname;
+const hasPublic = fs.existsSync(path.join(context, 'public'));
+
+const plugins = isProd
+  ? []
+  : [
+    new WebpackPluginServe({
+      hmr: false, // switch off, Chrome WASM memory leak
+      liveReload: false, // explict off, overrides hmr
+      port: 3000,
+      progress: false, // since we have hmr off, disable
+      static: path.join(process.cwd(), '/build')
+    })
+  ];
+
+module.exports = merge(
+  baseConfig({
+    alias: findPackages().reduce((alias, { dir, name }) => {
+      alias[name] = path.resolve(context, `../${dir}/src`);
+
+      return alias;
+    }, {}),
+    context
+  }),
+  {
     devtool,
-    entry: [
-      '@babel/polyfill',
-      `./src/${name}.tsx`,
-      isProd
-        ? null
-        : null // 'webpack-plugin-serve/client'
-    ].filter((entry) => entry),
-    mode: ENV,
-    module: {
-      rules: [
-        {
-          exclude: /(node_modules)/,
-          test: /\.css$/,
-          use: [
-            isProd
-              ? MiniCssExtractPlugin.loader
-              : require.resolve('style-loader'),
-            {
-              loader: require.resolve('css-loader'),
-              options: {
-                importLoaders: 1
-              }
-            }
-          ]
-        },
-        {
-          include: /node_modules/,
-          test: /\.css$/,
-          use: [
-            isProd
-              ? MiniCssExtractPlugin.loader
-              : require.resolve('style-loader'),
-            require.resolve('css-loader')
-          ]
-        },
-        {
-          exclude: /(node_modules)/,
-          test: /\.(js|ts|tsx)$/,
-          use: [
-            require.resolve('thread-loader'),
-            {
-              loader: require.resolve('babel-loader'),
-              options: require('@polkadot/dev/config/babel')
-            }
-          ]
-        },
-        {
-          test: /\.md$/,
-          use: [
-            require.resolve('html-loader'),
-            require.resolve('markdown-loader')
-          ]
-        },
-        {
-          test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
-          use: [
-            {
-              loader: require.resolve('url-loader'),
-              options: {
-                esModule: false,
-                limit: 10000,
-                name: 'static/[name].[hash:8].[ext]'
-              }
-            }
-          ]
-        },
-        {
-          test: [/\.eot$/, /\.ttf$/, /\.svg$/, /\.woff$/, /\.woff2$/],
-          use: [
-            {
-              loader: require.resolve('file-loader'),
-              options: {
-                esModule: false,
-                name: 'static/[name].[hash:8].[ext]'
-              }
-            }
-          ]
-        }
-      ]
-    },
-    node: {
-      child_process: 'empty',
-      dgram: 'empty',
-      fs: 'empty',
-      net: 'empty',
-      tls: 'empty'
-    },
-    optimization: {
-      runtimeChunk: 'single',
-      splitChunks: {
-        cacheGroups: {
-          polkadotJs: {
-            chunks: 'initial',
-            enforce: true,
-            name: 'polkadotjs',
-            test: /node_modules\/(@polkadot\/wasm-crypto)/
-          },
-          vendorOther: {
-            chunks: 'initial',
-            enforce: true,
-            name: 'vendor',
-            test: /node_modules\/(asn1|bn\.js|buffer|cuint|elliptic|lodash|moment|readable-stream|rxjs)/
-          },
-          vendorReact: {
-            chunks: 'initial',
-            enforce: true,
-            name: 'react',
-            test: /node_modules\/(chart|i18next|react|semantic-ui)/
-          }
-        }
-      }
-    },
-    output: {
-      chunkFilename: '[name].[chunkhash:8].js',
-      filename: '[name].[hash:8].js',
-      globalObject: '(typeof self !== \'undefined\' ? self : this)',
-      path: path.join(context, 'build'),
-      publicPath: ''
-    },
-    performance: {
-      hints: false
-    },
     plugins: plugins.concat([
-      new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
-      new webpack.DefinePlugin({
-        'process.env': {
-          NODE_ENV: JSON.stringify(ENV),
-          VERSION: JSON.stringify(pkgJson.version),
-          WS_URL: JSON.stringify(process.env.WS_URL)
-        }
-      }),
       new HtmlWebpackPlugin({
         PAGE_TITLE: 'Polkadot/Substrate Portal',
         inject: true,
-        template: path.join(context, `${hasPublic ? 'public/' : ''}${name}.html`)
-      }),
-      new webpack.optimize.SplitChunksPlugin(),
-      new MiniCssExtractPlugin({
-        filename: '[name].[contenthash:8].css'
-      }),
-      isProd
-        ? null
-        : new WebpackPluginServe({
-          hmr: false, // switch off, Chrome WASM memory leak
-          liveReload: false, // explict off, overrides hmr
-          port: 3000,
-          progress: false, // since we have hmr off, disable
-          static: path.join(process.cwd(), '/build')
-        })
-    ]).filter((plugin) => plugin),
-    resolve: {
-      alias,
-      extensions: ['.js', '.jsx', '.ts', '.tsx']
-    },
-    watch: !isProd,
-    watchOptions: {
-      ignored: ['.yarn', /build/, /node_modules/]
-    }
-  };
-}
-
-module.exports = createWebpack({
-  alias: findPackages().reduce((alias, { dir, name }) => {
-    alias[name] = path.resolve(__dirname, `../${dir}/src`);
-
-    return alias;
-  }, {}),
-  context: __dirname
-});
+        template: path.join(context, `${hasPublic ? 'public/' : ''}index.html`)
+      })
+    ])
+  }
+);

+ 1 - 0
packages/react-api/src/Api.tsx

@@ -23,6 +23,7 @@ import addressDefaults from '@polkadot/util-crypto/address/defaults';
 
 import ApiContext from './ApiContext';
 import registry from './typeRegistry';
+import './initSettings';
 
 interface Props {
   children: React.ReactNode;

+ 0 - 0
packages/apps/src/initSettings.ts → packages/react-api/src/initSettings.ts


+ 3 - 0
tsconfig.json

@@ -5,8 +5,11 @@
     "**/build/**/*"
   ],
   "compilerOptions": {
+    "jsx": "react",
     "baseUrl": ".",
     "paths": {
+      "@polkadot/apps/*": ["packages/apps/src/*"],
+      "@polkadot/apps": ["packages/apps/src"],
       "@polkadot/apps-config/*": [ "packages/apps-config/src/*" ],
       "@polkadot/apps-routing": [ "packages/apps-routing/src" ],
       "@polkadot/apps-routing/*": [ "packages/apps-routing/src/*" ],

文件差异内容过多而无法显示
+ 633 - 20
yarn.lock


部分文件因为文件数量过多而无法显示