diff options
author | August Skare <post@augustskare.no> | 2018-10-19 22:02:15 +0800 |
---|---|---|
committer | August Skare <post@augustskare.no> | 2018-10-19 22:05:09 +0800 |
commit | 7d7f54c751a2a5b8fca6791fb6685f4b5f969fff (patch) | |
tree | ab720f884ddf74953e119c7207ef4e52eb1760aa /packages/dev-tools-pages | |
parent | 736e1717fa4e59594e76694f7f6cc9dd0b45f1a9 (diff) | |
download | dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar.gz dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar.bz2 dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar.lz dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar.xz dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.tar.zst dexon-0x-contracts-7d7f54c751a2a5b8fca6791fb6685f4b5f969fff.zip |
Feature/build step (#2)
* BundleAnalyzerPlugin
* lazy load highlight.js
* seperate bundles for each page
* prerender apps to html on build
* preload important font files
* dont prerender code copy button
* fix woff2 variant of font
* added missing doctype
* remove metatags component
Diffstat (limited to 'packages/dev-tools-pages')
22 files changed, 195 insertions, 107 deletions
diff --git a/packages/dev-tools-pages/.gitignore b/packages/dev-tools-pages/.gitignore index 6446c8579..9e9db7dae 100644 --- a/packages/dev-tools-pages/.gitignore +++ b/packages/dev-tools-pages/.gitignore @@ -1 +1,2 @@ -/public/fonts
\ No newline at end of file +public +assets/fonts
\ No newline at end of file diff --git a/packages/dev-tools-pages/assets/crawl.html b/packages/dev-tools-pages/assets/crawl.html new file mode 100644 index 000000000..9135c3ede --- /dev/null +++ b/packages/dev-tools-pages/assets/crawl.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <title>Document</title> +</head> +<body> + +<ul> +<li><a href="/compiler">Compiler</a></li> +<li><a href="/cov">Cov</a></li> +<li><a href="/profiler">Profiler</a></li> +<li><a href="/trace">Trace</a></li> + +</ul> + +</body> +</html>
\ No newline at end of file diff --git a/packages/dev-tools-pages/public/favicons/compiler.ico b/packages/dev-tools-pages/assets/favicons/compiler.ico Binary files differindex e43c5fc8a..e43c5fc8a 100644 --- a/packages/dev-tools-pages/public/favicons/compiler.ico +++ b/packages/dev-tools-pages/assets/favicons/compiler.ico diff --git a/packages/dev-tools-pages/public/favicons/cov.ico b/packages/dev-tools-pages/assets/favicons/cov.ico Binary files differindex 4f1172186..4f1172186 100644 --- a/packages/dev-tools-pages/public/favicons/cov.ico +++ b/packages/dev-tools-pages/assets/favicons/cov.ico diff --git a/packages/dev-tools-pages/public/favicons/profiler.ico b/packages/dev-tools-pages/assets/favicons/profiler.ico Binary files differindex 65d38812b..65d38812b 100644 --- a/packages/dev-tools-pages/public/favicons/profiler.ico +++ b/packages/dev-tools-pages/assets/favicons/profiler.ico diff --git a/packages/dev-tools-pages/public/favicons/trace.ico b/packages/dev-tools-pages/assets/favicons/trace.ico Binary files differindex af00455d4..af00455d4 100644 --- a/packages/dev-tools-pages/public/favicons/trace.ico +++ b/packages/dev-tools-pages/assets/favicons/trace.ico diff --git a/packages/dev-tools-pages/assets/index.html b/packages/dev-tools-pages/assets/index.html new file mode 100644 index 000000000..5ab1a45f1 --- /dev/null +++ b/packages/dev-tools-pages/assets/index.html @@ -0,0 +1,14 @@ +<!DOCTYPE html> +<html lang="en"> +<head> + <meta charset="UTF-8"> + <meta name="viewport" content="width=device-width, initial-scale=1.0"> + <meta http-equiv="X-UA-Compatible" content="ie=edge"> + <link rel="preload" href="/fonts/MaisonNeue-Book-subset.woff2" as="font" type="font/woff2" crossorigin> + <link rel="preload" href="/fonts/MaisonNeue-Bold-subset.woff2" as="font" type="font/woff2" crossorigin> + <title><%= htmlWebpackPlugin.options.title %></title> +</head> +<body> + <div id="app"></div> +</body> +</html>
\ No newline at end of file diff --git a/packages/dev-tools-pages/package.json b/packages/dev-tools-pages/package.json index 8fb4bed7b..eb34e3715 100644 --- a/packages/dev-tools-pages/package.json +++ b/packages/dev-tools-pages/package.json @@ -7,7 +7,7 @@ "private": true, "description": "0x Dev tools pages", "scripts": { - "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production", + "build": "node --max_old_space_size=8192 ../../node_modules/.bin/webpack --mode production && react-snap", "build:ci": "yarn build", "build:dev": "../../node_modules/.bin/webpack --mode development", "clean": "shx rm -f public/bundle*", @@ -28,7 +28,7 @@ "styled-normalize": "^8.0.1" }, "devDependencies": { - "@reach/router": "^1.2.1", + "@types/highlight.js": "^9.12.3", "@types/lodash": "4.14.104", "@types/node": "*", "@types/reach__router": "^1.2.0", @@ -40,11 +40,15 @@ "@types/react-tap-event-plugin": "0.0.30", "@types/styled-components": "^4.0.1", "awesome-typescript-loader": "^5.2.1", + "clean-webpack-plugin": "^0.1.19", + "copy-webpack-plugin": "^4.5.4", "copyfiles": "^2.0.0", "css-loader": "0.23.x", + "html-webpack-plugin": "^3.2.0", "less-loader": "^4.1.0", "make-promises-safe": "^1.1.0", "raw-loader": "^0.5.1", + "react-snap": "^1.19.0", "react-svg-loader": "^2.1.0", "shx": "^0.2.2", "source-map-loader": "^0.2.4", @@ -55,7 +59,11 @@ "typescript": "3.0.1", "uglifyjs-webpack-plugin": "^2.0.1", "webpack": "^4.20.2", + "webpack-bundle-analyzer": "^3.0.3", "webpack-cli": "3.1.2", "webpack-dev-server": "^3.1.9" + }, + "reactSnap": { + "source": "public" } } diff --git a/packages/dev-tools-pages/pages.js b/packages/dev-tools-pages/pages.js new file mode 100644 index 000000000..581904068 --- /dev/null +++ b/packages/dev-tools-pages/pages.js @@ -0,0 +1,72 @@ +const pages = [ + { + title: 'sol-compiler', + filename: 'compiler/index.html', + template: 'assets/index.html', + chunks: ['compiler'], + favicon: 'assets/favicons/compiler.ico', + minify: true, + meta: { + description: 'Solidity compilation that just works', + 'og-title': { property: 'og:title', content: 'sol-compiler' }, + 'og-description': { property: 'og:description', content: 'Solidity compilation that just works' }, + 'og-type': { property: 'og:type', content: 'website' }, + 'og-image': { property: 'og:image', content: '' }, + 'twitter:site': '@0xproject', + 'twitter:image': '', + }, + }, + { + title: 'sol-cov', + filename: 'cov/index.html', + template: 'assets/index.html', + chunks: ['cov'], + favicon: 'assets/favicons/cov.ico', + minify: true, + meta: { + description: 'Solidity code coverage', + 'og-title': { property: 'og:title', content: 'sol-cov' }, + 'og-description': { property: 'og:description', content: 'Solidity code coverage' }, + 'og-type': { property: 'og:type', content: 'website' }, + 'og-image': { property: 'og:image', content: '' }, + 'twitter:site': '@0xproject', + 'twitter:image': '', + }, + }, + { + title: 'sol-profiler', + filename: 'profiler/index.html', + template: 'assets/index.html', + chunks: ['profiler'], + favicon: 'assets/favicons/profiler.ico', + minify: true, + meta: { + description: 'Gas profiling for Solidity', + 'og-title': { property: 'og:title', content: 'sol-profiler' }, + 'og-description': { property: 'og:description', content: 'Gas profiling for Solidity' }, + 'og-type': { property: 'og:type', content: 'website' }, + 'og-image': { property: 'og:image', content: '' }, + 'twitter:site': '@0xproject', + 'twitter:image': '', + }, + }, + { + title: 'sol-trace', + filename: 'trace/index.html', + template: 'assets/index.html', + chunks: ['trace'], + favicon: 'assets/favicons/trace.ico', + minify: true, + meta: { + description: 'Human-readable stack traces', + 'og-title': { property: 'og:title', content: 'sol-trace' }, + 'og-description': { property: 'og:description', content: 'Human-readable stack traces' }, + 'og-type': { property: 'og:type', content: 'website' }, + 'og-image': { property: 'og:image', content: '' }, + 'twitter:site': '@0xproject', + 'twitter:image': '', + }, + }, +]; + +module.exports = pages; diff --git a/packages/dev-tools-pages/public/index.html b/packages/dev-tools-pages/public/index.html deleted file mode 100644 index f8131aece..000000000 --- a/packages/dev-tools-pages/public/index.html +++ /dev/null @@ -1,15 +0,0 @@ -<!DOCTYPE html> -<html> - -<head> - <meta charset="utf-8"> - <meta name="viewport" content="width=device-width, initial-scale=1"> - <title>0x: The Protocol for Trading Tokens</title> -</head> - -<body> - <div id="app"></div> - <script type="text/javascript" crossorigin="anonymous" src="/bundle.js" charset="utf-8"></script> -</body> - -</html>
\ No newline at end of file diff --git a/packages/dev-tools-pages/ts/pages/Base.tsx b/packages/dev-tools-pages/ts/components/Base.tsx index 7bb578611..16e9560f0 100644 --- a/packages/dev-tools-pages/ts/pages/Base.tsx +++ b/packages/dev-tools-pages/ts/components/Base.tsx @@ -2,7 +2,6 @@ import * as React from 'react'; import ThemeContext from 'ts/context'; import GlobalStyles from 'ts/globalStyles'; -import MetaTags from 'ts/components/MetaTags'; import Header from 'ts/components/Header'; import Hero from 'ts/components/Hero'; import Footer from 'ts/components/Footer'; @@ -15,7 +14,6 @@ interface BaseProps { function Base(props: BaseProps) { return ( <ThemeContext.Provider value={props.context}> - <MetaTags /> <GlobalStyles /> <Header /> <Hero /> diff --git a/packages/dev-tools-pages/ts/components/Code.tsx b/packages/dev-tools-pages/ts/components/Code.tsx index 44d1cb99c..72b3e1af7 100644 --- a/packages/dev-tools-pages/ts/components/Code.tsx +++ b/packages/dev-tools-pages/ts/components/Code.tsx @@ -69,8 +69,8 @@ class Code extends React.Component<CodeProps, CodeState> { const { language, children } = this.props; if (language !== undefined) { - const { highlight } = await import(/* webpackChunkName: 'highlight.js' */ 'highlight.js'); - const { value: hlCode } = highlight(language, children as string); + const { default: hljs } = await System.import(/* webpackChunkName: 'highlightjs' */ 'ts/highlight'); + const { value: hlCode } = hljs.highlight(language, children as string); this.setState({ hlCode }); } } @@ -103,7 +103,7 @@ class Code extends React.Component<CodeProps, CodeState> { <StyledCode>{this.props.children}</StyledCode> )} </StyledPre> - <Button onClick={this.handleCopy}>Copy</Button> + {navigator.userAgent !== 'ReactSnap' ? <Button onClick={this.handleCopy}>Copy</Button> : null} {!('clipboard' in navigator) ? ( <CopyInput readOnly aria-hidden="true" ref={this.code} value={children} /> ) : null} diff --git a/packages/dev-tools-pages/ts/components/MetaTags.tsx b/packages/dev-tools-pages/ts/components/MetaTags.tsx deleted file mode 100644 index 9bb33f7ab..000000000 --- a/packages/dev-tools-pages/ts/components/MetaTags.tsx +++ /dev/null @@ -1,28 +0,0 @@ -import * as React from 'react'; -import { Helmet } from 'react-helmet'; - -import { withContext, Props } from './withContext'; - -interface MetaTagsProps extends Props { - imgSrc?: string; -} - -function MetaTags(props: MetaTagsProps) { - const { title, imgSrc = '/images/og_image.png' } = props; - const description = props.tagline; - return ( - <Helmet> - <title>{props.title}</title> - <meta name="description" content={description} /> - <link rel="shortcut icon" href={`/favicons/${props.name}.ico`} /> - <meta property="og:title" content={title} /> - <meta property="og:description" content={description} /> - <meta property="og:type" content="website" /> - <meta property="og:image" content={imgSrc} /> - <meta name="twitter:site" content="@0xproject" /> - <meta name="twitter:image" content={imgSrc} /> - </Helmet> - ); -} - -export default withContext(MetaTags); diff --git a/packages/dev-tools-pages/ts/globalStyles.tsx b/packages/dev-tools-pages/ts/globalStyles.tsx index e8ef630da..13ecde7aa 100644 --- a/packages/dev-tools-pages/ts/globalStyles.tsx +++ b/packages/dev-tools-pages/ts/globalStyles.tsx @@ -11,21 +11,21 @@ const BaseStyles = createGlobalStyle` @font-face { font-family: "Maison Neue"; - src: url("/fonts/MaisonNeue-Book-subset.woff") format("woff"); + src: url("/fonts/MaisonNeue-Book-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Book-subset.woff") format("woff"); font-weight: 300; font-display: swap; unicode-range: U+20-7E; } @font-face { font-family: "Maison Neue"; - src: url("/fonts/MaisonNeue-Bold-subset.woff") format("woff"); + src: url("/fonts/MaisonNeue-Bold-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Bold-subset.woff") format("woff"); font-weight: 500; font-display: swap; unicode-range: U+20-7E; } @font-face { font-family: "Maison Neue Mono"; - src: url("/fonts/MaisonNeue-Mono-subset.woff") format("woff"); + src: url("/fonts/MaisonNeue-Mono-subset.woff2") format("woff2"), url("/fonts/MaisonNeue-Mono-subset.woff") format("woff"); font-weight: 300; font-display: optional; unicode-range: U+20-7E; diff --git a/packages/dev-tools-pages/ts/globals.d.ts b/packages/dev-tools-pages/ts/globals.d.ts index da026a198..07871a74b 100644 --- a/packages/dev-tools-pages/ts/globals.d.ts +++ b/packages/dev-tools-pages/ts/globals.d.ts @@ -1,6 +1,8 @@ declare module 'whatwg-fetch'; declare module 'react-document-title'; +declare var System: any; + declare module '*.json' { const json: any; /* tslint:disable */ diff --git a/packages/dev-tools-pages/ts/highlight.tsx b/packages/dev-tools-pages/ts/highlight.tsx new file mode 100644 index 000000000..0c4602d51 --- /dev/null +++ b/packages/dev-tools-pages/ts/highlight.tsx @@ -0,0 +1,6 @@ +const highlight = require('highlight.js/lib/highlight'); +const javascript = require('highlight.js/lib/languages/javascript'); + +highlight.registerLanguage('javascript', javascript); + +export default highlight; diff --git a/packages/dev-tools-pages/ts/index.tsx b/packages/dev-tools-pages/ts/index.tsx deleted file mode 100644 index b185e270a..000000000 --- a/packages/dev-tools-pages/ts/index.tsx +++ /dev/null @@ -1,37 +0,0 @@ -import * as React from 'react'; -import { render } from 'react-dom'; -import { Router, Link } from '@reach/router'; - -import Trace from 'ts/pages/Trace'; -import Compiler from 'ts/pages/Compiler'; -import Cov from 'ts/pages/Cov'; -import Profiler from 'ts/pages/Profiler'; - -const Index = (props: any) => ( - <ul> - <li> - <Link to="/trace">sol-trace</Link> - </li> - <li> - <Link to="/compiler">sol-compiler</Link> - </li> - <li> - <Link to="/cov">sol-cov</Link> - </li> - <li> - <Link to="/profiler">sol-profiler</Link> - </li> - </ul> -); - -const App = () => ( - <Router> - <Trace path="/trace" /> - <Compiler path="/compiler" /> - <Cov path="/cov" /> - <Profiler path="/profiler" /> - <Index default /> - </Router> -); - -render(<App />, document.getElementById('app')); diff --git a/packages/dev-tools-pages/ts/pages/Compiler.tsx b/packages/dev-tools-pages/ts/pages/Compiler.tsx index 79c9f52e4..35c810cb3 100644 --- a/packages/dev-tools-pages/ts/pages/Compiler.tsx +++ b/packages/dev-tools-pages/ts/pages/Compiler.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; +import { render, hydrate } from 'react-dom'; import context from 'ts/context/compiler'; -import Base from './Base'; +import Base from 'ts/components/Base'; import Container from 'ts/components/Container'; import Main from 'ts/components/Main'; import ContentBlock from 'ts/components/ContentBlock'; @@ -11,7 +12,7 @@ import InlineCode from 'ts/components/InlineCode'; import List from 'ts/components/List'; import CompilerComponent from 'ts/components/Compiler'; -function Compiler(props: any) { +function Compiler() { return ( <Base context={context}> <Container> @@ -52,4 +53,10 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi ); } -export default Compiler; +const root = document.getElementById('app'); + +if (root.hasChildNodes()) { + hydrate(<Compiler />, root); +} else { + render(<Compiler />, root); +} diff --git a/packages/dev-tools-pages/ts/pages/Cov.tsx b/packages/dev-tools-pages/ts/pages/Cov.tsx index b7405f8f9..e835e5c82 100644 --- a/packages/dev-tools-pages/ts/pages/Cov.tsx +++ b/packages/dev-tools-pages/ts/pages/Cov.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; +import { render, hydrate } from 'react-dom'; import context from 'ts/context/cov'; -import Base from './Base'; +import Base from 'ts/components/Base'; import Container from 'ts/components/Container'; import Main from 'ts/components/Main'; import ContentBlock from 'ts/components/ContentBlock'; @@ -11,7 +12,7 @@ import InlineCode from 'ts/components/InlineCode'; import List from 'ts/components/List'; import Intro from 'ts/components/Intro'; -function Cov(props: any) { +function Cov() { return ( <Base context={context}> <Container> @@ -58,4 +59,10 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi ); } -export default Cov; +const root = document.getElementById('app'); + +if (root.hasChildNodes()) { + hydrate(<Cov />, root); +} else { + render(<Cov />, root); +} diff --git a/packages/dev-tools-pages/ts/pages/Profiler.tsx b/packages/dev-tools-pages/ts/pages/Profiler.tsx index d129d6427..9f8b46b9c 100644 --- a/packages/dev-tools-pages/ts/pages/Profiler.tsx +++ b/packages/dev-tools-pages/ts/pages/Profiler.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; +import { render, hydrate } from 'react-dom'; import context from 'ts/context/profiler'; -import Base from './Base'; +import Base from 'ts/components/Base'; import Container from 'ts/components/Container'; import Main from 'ts/components/Main'; import ContentBlock from 'ts/components/ContentBlock'; @@ -11,7 +12,7 @@ import InlineCode from 'ts/components/InlineCode'; import List from 'ts/components/List'; import Intro from 'ts/components/Intro'; -function Profiler(props: any) { +function Profiler() { return ( <Base context={context}> <Container> @@ -58,4 +59,10 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi ); } -export default Profiler; +const root = document.getElementById('app'); + +if (root.hasChildNodes()) { + hydrate(<Profiler />, root); +} else { + render(<Profiler />, root); +} diff --git a/packages/dev-tools-pages/ts/pages/Trace.tsx b/packages/dev-tools-pages/ts/pages/Trace.tsx index 5dddf027e..be5acdac4 100644 --- a/packages/dev-tools-pages/ts/pages/Trace.tsx +++ b/packages/dev-tools-pages/ts/pages/Trace.tsx @@ -1,7 +1,8 @@ import * as React from 'react'; +import { render, hydrate } from 'react-dom'; import context from 'ts/context/trace'; -import Base from './Base'; +import Base from 'ts/components/Base'; import Container from 'ts/components/Container'; import Main from 'ts/components/Main'; import ContentBlock from 'ts/components/ContentBlock'; @@ -11,7 +12,7 @@ import InlineCode from 'ts/components/InlineCode'; import List from 'ts/components/List'; import TraceComponent from 'ts/components/Trace'; -function Trace(props: any) { +function Trace() { return ( <Base context={context}> <TraceComponent /> @@ -52,4 +53,10 @@ const artifactAdapter = new SolCompilerArtifactAdapter(artifactsDir, contractsDi ); } -export default Trace; +const root = document.getElementById('app'); + +if (root.hasChildNodes()) { + hydrate(<Trace />, root); +} else { + render(<Trace />, root); +} diff --git a/packages/dev-tools-pages/webpack.config.js b/packages/dev-tools-pages/webpack.config.js index a016c6b04..d025737f7 100644 --- a/packages/dev-tools-pages/webpack.config.js +++ b/packages/dev-tools-pages/webpack.config.js @@ -1,13 +1,24 @@ const path = require('path'); const webpack = require('webpack'); const TerserPlugin = require('terser-webpack-plugin'); +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; +const HtmlWebpackPlugin = require('html-webpack-plugin'); const childProcess = require('child_process'); +const CopyWebpackPlugin = require('copy-webpack-plugin'); +const CleanWebpackPlugin = require('clean-webpack-plugin'); + +const pages = require('./pages'); const config = { - entry: ['./ts/index.tsx'], + entry: { + compiler: './ts/pages/Compiler.tsx', + cov: './ts/pages/Cov.tsx', + profiler: './ts/pages/Profiler.tsx', + trace: './ts/pages/Trace.tsx', + }, output: { path: path.join(__dirname, '/public'), - filename: 'bundle.js', + filename: 'bundle-[name].js', chunkFilename: 'bundle-[name].js', publicPath: '/', }, @@ -70,17 +81,25 @@ const config = { }; module.exports = (_env, argv) => { - let plugins = []; + let plugins = [ + new CleanWebpackPlugin('public'), + ...pages.map(p => new HtmlWebpackPlugin(p)), + new CopyWebpackPlugin([{ from: 'assets/crawl.html', to: 'index.html' }, { from: 'assets/fonts', to: 'fonts' }]), + ]; if (argv.mode === 'development') { config.mode = 'development'; } else { config.mode = 'production'; + config.output.filename = 'bundle-[name].[chunkhash].js'; + config.output.chunkFilename = 'bundle-[name].[chunkhash].js'; + plugins = plugins.concat([ new webpack.DefinePlugin({ 'process.env': { - NODE_ENV: JSON.stringify(process.env.NODE_ENV), + NODE_ENV: JSON.stringify(process.env.NODE_ENV || config.mode), }, }), + //new BundleAnalyzerPlugin(), ]); } console.log('i 「atl」: Mode: ', config.mode); |