diff --git a/.gitignore b/.gitignore index b973a473c..6e69f36af 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,12 @@ .DS_Store node_modules +landing/node_modules +landing/dist lib/node_modules -web/node_modules/* +web/node_modules web/dist server/dist -server/node_modules/* +server/node_modules server/secrets server/facts .eslintcache diff --git a/.lintstagedrc.js b/.lintstagedrc.js index d0e8a89ee..ba9226301 100644 --- a/.lintstagedrc.js +++ b/.lintstagedrc.js @@ -1,21 +1,24 @@ const { CLIEngine } = require('eslint'); const cli = new CLIEngine({}); module.exports = { '*.js': (files) => 'eslint --cache --fix --max-warnings=0 ' + files.filter((file) => !cli.isPathIgnored(file)).join(' '), 'lib/**/*.js': function libFlow(files) { return 'yarn workspace lib flow --quiet'; }, '{web,lib}/**/*.js': function webFlow(files) { return 'yarn workspace web flow --quiet'; }, '{native,lib}/**/*.js': function nativeFlow(files) { return 'yarn workspace native flow --quiet'; }, '{server,web,lib}/**/*.js': function serverFlow(files) { return 'yarn workspace server flow --quiet'; }, + '{landing,lib}/**/*.js': function serverFlow(files) { + return 'yarn workspace landing flow --quiet'; + }, }; diff --git a/landing/.eslintrc.json b/landing/.eslintrc.json new file mode 100644 index 000000000..e5a34aec6 --- /dev/null +++ b/landing/.eslintrc.json @@ -0,0 +1,5 @@ +{ + "env": { + "browser": true + } +} diff --git a/landing/.flowconfig b/landing/.flowconfig new file mode 100644 index 000000000..cbb3ecb50 --- /dev/null +++ b/landing/.flowconfig @@ -0,0 +1,25 @@ +[options] +module.name_mapper.extension='css' -> '/flow/CSSModule.js.flow' +esproposal.optional_chaining=enable +esproposal.nullish_coalescing=enable + +[lints] +sketchy-null-number=warn +sketchy-null-mixed=warn +sketchy-number=warn +untyped-type-import=warn +nonstrict-import=warn +deprecated-type=warn +unsafe-getters-setters=warn +unnecessary-invariant=warn +signature-verification-failure=warn +deprecated-utility=error + +[strict] +deprecated-type +nonstrict-import +sketchy-null +unclear-type +unsafe-getters-setters +untyped-import +untyped-type-import diff --git a/landing/babel.config.cjs b/landing/babel.config.cjs new file mode 100644 index 000000000..c62ca93f2 --- /dev/null +++ b/landing/babel.config.cjs @@ -0,0 +1,10 @@ +module.exports = { + presets: ['@babel/preset-react', '@babel/preset-flow'], + plugins: [ + '@babel/plugin-proposal-class-properties', + '@babel/plugin-proposal-object-rest-spread', + '@babel/plugin-proposal-optional-chaining', + '@babel/plugin-proposal-nullish-coalescing-operator', + ['@babel/plugin-transform-runtime', { useESModules: true }], + ], +}; diff --git a/landing/flow/CSSModule.js.flow b/landing/flow/CSSModule.js.flow new file mode 100644 index 000000000..6029a65c9 --- /dev/null +++ b/landing/flow/CSSModule.js.flow @@ -0,0 +1,3 @@ +// @flow + +declare export default { [key: string]: string }; diff --git a/landing/landing.react.js b/landing/landing.react.js new file mode 100644 index 000000000..49277823e --- /dev/null +++ b/landing/landing.react.js @@ -0,0 +1,9 @@ +// @flow + +import * as React from 'react'; + +function Landing() { + return Hello World!; +} + +export default Landing; diff --git a/landing/package.json b/landing/package.json new file mode 100644 index 000000000..95f609e2f --- /dev/null +++ b/landing/package.json @@ -0,0 +1,51 @@ +{ + "name": "landing", + "version": "0.0.1", + "type": "module", + "private": true, + "license": "BSD-3-Clause", + "scripts": { + "clean": "rm -rf dist/ && rm -rf node_modules/", + "dev": "yarn concurrently --names=\"NODESSR,BROWSER\" -c \"bgBlue.bold,bgMagenta.bold\" \"yarn webpack --config webpack.config.cjs --config-name=server --watch\" \"yarn webpack-dev-server --hot --config webpack.config.cjs --config-name=browser\"", + "prod": "yarn webpack --config webpack.config.cjs --env prod --progress" + }, + "devDependencies": { + "@babel/core": "^7.13.14", + "@babel/plugin-proposal-class-properties": "^7.13.0", + "@babel/plugin-proposal-nullish-coalescing-operator": "^7.13.8", + "@babel/plugin-proposal-object-rest-spread": "^7.13.8", + "@babel/plugin-proposal-optional-chaining": "^7.13.12", + "@babel/plugin-transform-react-constant-elements": "^7.13.13", + "@babel/plugin-transform-runtime": "^7.13.10", + "@babel/preset-env": "^7.13.12", + "@babel/preset-flow": "^7.13.13", + "@babel/preset-react": "^7.13.13", + "@hot-loader/react-dom": "16.13.0", + "assets-webpack-plugin": "^3.9.7", + "babel-loader": "^8.1.0", + "babel-plugin-transform-remove-console": "^6.9.4", + "clean-webpack-plugin": "^3.0.0", + "concurrently": "^5.3.0", + "css-loader": "^4.3.0", + "flow-bin": "^0.122.0", + "flow-typed": "^3.2.1", + "mini-css-extract-plugin": "^0.11.2", + "optimize-css-assets-webpack-plugin": "^5.0.3", + "style-loader": "^1.2.1", + "terser-webpack-plugin": "^2.1.2", + "url-loader": "^2.2.0", + "webpack": "^4.41.0", + "webpack-cli": "^3.3.9", + "webpack-dev-server": "^3.11.0" + }, + "dependencies": { + "@babel/runtime": "^7.13.10", + "core-js": "^3.6.5", + "invariant": "^2.2.4", + "isomorphic-fetch": "^2.2.1", + "lib": "0.0.1", + "react": "16.13.1", + "react-dom": "16.13.1", + "react-hot-loader": "^4.12.14" + } +} diff --git a/landing/root.js b/landing/root.js new file mode 100644 index 000000000..acd6eea41 --- /dev/null +++ b/landing/root.js @@ -0,0 +1,12 @@ +// @flow + +import * as React from 'react'; +import { hot } from 'react-hot-loader/root'; + +import Landing from './landing.react'; + +function RootComponent() { + return ; +} + +export default hot(RootComponent); diff --git a/landing/script.js b/landing/script.js new file mode 100644 index 000000000..f9a9f9aa1 --- /dev/null +++ b/landing/script.js @@ -0,0 +1,14 @@ +// @flow + +import 'isomorphic-fetch'; + +import invariant from 'invariant'; +import React from 'react'; +import ReactDOM from 'react-dom'; + +import Root from './root'; + +const root = document.getElementById('react-root'); +invariant(root, "cannot find id='react-root' element!"); + +ReactDOM.render(, root); diff --git a/landing/webpack.config.cjs b/landing/webpack.config.cjs new file mode 100644 index 000000000..b94fdc6a0 --- /dev/null +++ b/landing/webpack.config.cjs @@ -0,0 +1,78 @@ +const path = require('path'); +const AssetsPlugin = require('assets-webpack-plugin'); + +const babelConfig = require('./babel.config.cjs'); +const { + createProdBrowserConfig, + createDevBrowserConfig, + createNodeServerRenderingConfig, +} = require('lib/webpack/shared.cjs'); + +const baseBrowserConfig = { + entry: { + browser: ['./script.js'], + }, + output: { + filename: 'prod.[hash:12].build.js', + path: path.join(__dirname, 'dist'), + }, + resolve: { + alias: { + '../images': path.resolve('../server/images'), + }, + }, +}; + +const baseDevBrowserConfig = { + ...baseBrowserConfig, + output: { + ...baseBrowserConfig.output, + filename: 'dev.build.js', + pathinfo: true, + publicPath: 'http://localhost:8082/', + }, + devServer: { + hot: true, + port: 8082, + contentBase: path.join(__dirname, 'dist'), + headers: { 'Access-Control-Allow-Origin': '*' }, + }, +}; + +const baseProdBrowserConfig = { + ...baseBrowserConfig, + plugins: [ + new AssetsPlugin({ + filename: 'assets.json', + path: path.join(__dirname, 'dist'), + }), + ], +}; + +const baseNodeServerRenderingConfig = { + externals: ['react', 'react-dom', 'react-redux'], + entry: { + server: ['./landing.react.js'], + }, + output: { + filename: 'landing.build.cjs', + library: 'landing', + libraryTarget: 'commonjs2', + path: path.join(__dirname, 'dist'), + }, +}; + +module.exports = function (env) { + const browserConfig = env === 'prod' + ? createProdBrowserConfig(baseProdBrowserConfig, babelConfig) + : createDevBrowserConfig(baseDevBrowserConfig, babelConfig); + const nodeConfig = createNodeServerRenderingConfig( + baseNodeServerRenderingConfig, + babelConfig, + ); + const nodeServerRenderingConfig = { + ...nodeConfig, + mode: env === 'dev' ? 'development' : 'production', + }; + return [browserConfig, nodeServerRenderingConfig]; +}; diff --git a/package.json b/package.json index b81caeaee..ab071f47f 100644 --- a/package.json +++ b/package.json @@ -1,38 +1,39 @@ { "private": true, "license": "BSD-3-Clause", "workspaces": [ "lib", "web", "native", - "server" + "server", + "landing" ], "scripts": { - "clean": "yarn workspace lib clean && yarn workspace web clean && yarn workspace native clean && yarn workspace server clean && rm -rf node_modules/", + "clean": "yarn workspace lib clean && yarn workspace web clean && yarn workspace native clean && yarn workspace server clean && yarn workspace landing clean && rm -rf node_modules/", "cleaninstall": "yarn clean && yarn", "eslint": "eslint .", "eslint:fix": "eslint --fix ." }, "devDependencies": { "babel-eslint": "^10.1.0", "core-js": "^3.6.5", "eslint": "^6.8.0", "eslint-config-prettier": "^6.15.0", "eslint-plugin-flowtype": "^4.6.0", "eslint-plugin-import": "^2.20.1", "eslint-plugin-jest": "^23.8.2", "eslint-plugin-monorepo": "^0.2.1", "eslint-plugin-prettier": "^3.1.4", "eslint-plugin-react": "^7.19.0", "eslint-plugin-react-hooks": "^2.5.1", "eslint-plugin-react-native": "^3.8.1", "husky": "^4.2.3", "lint-staged": "^10.0.8", "prettier": "^2.1.2" }, "husky": { "hooks": { "pre-commit": "lint-staged" } } } diff --git a/server/misc/landing.html b/server/misc/landing.html new file mode 100644 index 000000000..945e4c2fd --- /dev/null +++ b/server/misc/landing.html @@ -0,0 +1,12 @@ + + + + + Hello world + + + +
+ + +