Commit d861d6b6 authored by Sam Gluck's avatar Sam Gluck
Browse files

Prepare repo for UI milestone 1:

- Amend webpack configurations: use terser-webpack-plugin to support
minification of >ES6 as uglify-js-webpack-plugin has moved away from the
now unsupported uglify-es library (https://github.com/webpack-contrib/uglifyjs-webpack-plugin/issues/349#issuecomment-417747256);
- Move ThemeProvider to the root App component and consolidate theme
into theme.ts;
- Update all dependencies to latest;
- Lock dependencies to exact version and add .npmrc to ensure this
restriction is applied for new dependencies;
parent 23a5ab20
save-exact=true
......@@ -5,7 +5,7 @@ const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const InterpolateHtmlPlugin = require('interpolate-html-plugin');
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
......@@ -84,10 +84,7 @@ module.exports = {
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx', '.tsx', '.ts'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
'~': paths.appSrc
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
......@@ -115,7 +112,6 @@ module.exports = {
options: {
formatter: eslintFormatter,
eslintPath: require.resolve('eslint'),
},
loader: require.resolve('eslint-loader'),
},
......@@ -138,14 +134,12 @@ module.exports = {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process JS with Babel.
{
test: /\.(ts|tsx|js|jsx|mjs)$/,
test: /\.tsx?$/,
include: paths.appSrc,
loader: require.resolve('awesome-typescript-loader'),
options: {
useBabel: true,
compact: true,
},
},
// "postcss" loader applies autoprefixer to our CSS.
......@@ -208,16 +202,16 @@ module.exports = {
],
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In development, this will be an empty string.
new InterpolateHtmlPlugin(env.raw),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
}),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In development, this will be an empty string.
new InterpolateHtmlPlugin(env.raw),
// Add module names to factory functions so they appear in browser profiler.
new webpack.NamedModulesPlugin(),
// Makes some environment variables available to the JS code, for example:
......
'use strict';
const TerserPlugin = require('terser-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const autoprefixer = require('autoprefixer');
const path = require('path');
const webpack = require('webpack');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const ManifestPlugin = require('webpack-manifest-plugin');
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
const InterpolateHtmlPlugin = require('interpolate-html-plugin');
const SWPrecacheWebpackPlugin = require('sw-precache-webpack-plugin');
const eslintFormatter = require('react-dev-utils/eslintFormatter');
const ModuleScopePlugin = require('react-dev-utils/ModuleScopePlugin');
......@@ -16,9 +17,6 @@ const getClientEnvironment = require('./env');
// Webpack uses `publicPath` to determine where the app is being served from.
// It requires a trailing slash, or the file assets will get an incorrect path.
const publicPath = paths.servedPath;
// Some apps do not use client-side routing with pushState.
// For these, "homepage" can be set to "." to enable relative asset paths.
const shouldUseRelativeAssetPaths = publicPath === './';
// Source maps are resource heavy and can cause out of memory issue for large source files.
const shouldUseSourceMap = process.env.GENERATE_SOURCEMAP !== 'false';
// `publicUrl` is just like `publicPath`, but we will provide it to our app
......@@ -37,15 +35,6 @@ if (env.stringified['process.env'].NODE_ENV !== '"production"') {
// Note: defined here because it will be used more than once.
const cssFilename = 'static/css/[name].[contenthash:8].css';
// ExtractTextPlugin expects the build output to be flat.
// (See https://github.com/webpack-contrib/extract-text-webpack-plugin/issues/27)
// However, our output is structured with css, js and media folders.
// To have this structure working with relative paths, we have to use custom options.
const extractTextPluginOptions = shouldUseRelativeAssetPaths
? // Making sure that the publicPath goes back to to build folder.
{ publicPath: Array(cssFilename.split('/').length).join('../') }
: {};
// This is the production configuration.
// It compiles slowly and is focused on producing a fast and minimal bundle.
// The development configuration is different and lives in a separate file.
......@@ -90,10 +79,7 @@ module.exports = {
// for React Native Web.
extensions: ['.web.js', '.mjs', '.js', '.json', '.web.jsx', '.jsx', '.tsx', '.ts'],
alias: {
// Support React Native Web
// https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/
'react-native': 'react-native-web',
'~': paths.appSrc,
},
plugins: [
// Prevents users from importing files from outside of src/ (or node_modules/).
......@@ -143,9 +129,8 @@ module.exports = {
name: 'static/media/[name].[hash:8].[ext]',
},
},
// Process JS with Babel.
{
test: /\.(ts|tsxjs|jsx|mjs)$/,
test: /\.tsx?$/,
include: paths.appSrc,
loader: require.resolve('awesome-typescript-loader'),
options: {
......@@ -167,50 +152,37 @@ module.exports = {
// in the main CSS file.
{
test: /\.css$/,
loader: ExtractTextPlugin.extract(
Object.assign(
{
fallback: {
loader: require.resolve('style-loader'),
options: {
hmr: false,
},
},
use: [
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
sourceMap: shouldUseSourceMap,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
},
loader: [
MiniCssExtractPlugin.loader,
{
loader: require.resolve('css-loader'),
options: {
importLoaders: 1,
minimize: true,
sourceMap: shouldUseSourceMap,
},
},
{
loader: require.resolve('postcss-loader'),
options: {
// Necessary for external CSS imports to work
// https://github.com/facebookincubator/create-react-app/issues/2677
ident: 'postcss',
plugins: () => [
require('postcss-flexbugs-fixes'),
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
],
flexbox: 'no-2009',
}),
],
},
extractTextPluginOptions
)
),
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},
],
},
// "file" loader makes sure assets end up in the `build` folder.
// When you `import` an asset, you get its filename.
......@@ -234,12 +206,6 @@ module.exports = {
],
},
plugins: [
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(env.raw),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
......@@ -257,35 +223,19 @@ module.exports = {
minifyURLs: true,
},
}),
// Makes some environment variables available in index.html.
// The public URL is available as %PUBLIC_URL% in index.html, e.g.:
// <link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
// In production, it will be an empty string unless you specify "homepage"
// in `package.json`, in which case it will be the pathname of that URL.
new InterpolateHtmlPlugin(env.raw),
// Makes some environment variables available to the JS code, for example:
// if (process.env.NODE_ENV === 'production') { ... }. See `./env.js`.
// It is absolutely essential that NODE_ENV was set to production here.
// Otherwise React will be compiled in the very slow development mode.
new webpack.DefinePlugin(env.stringified),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
warnings: false,
// Disabled because of an issue with Uglify breaking seemingly valid code:
// https://github.com/facebookincubator/create-react-app/issues/2376
// Pending further investigation:
// https://github.com/mishoo/UglifyJS2/issues/2011
comparisons: false,
},
mangle: {
safari10: true,
},
output: {
comments: false,
// Turned on because emoji and regex is not minified properly using default
// https://github.com/facebookincubator/create-react-app/issues/2488
ascii_only: true,
},
sourceMap: shouldUseSourceMap,
}),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin({
filename: cssFilename,
new MiniCssExtractPlugin({
filename: cssFilename
}),
// Generate a manifest file which contains a mapping of all asset filenames
// to their corresponding output file so that tools can pick it up without
......@@ -323,13 +273,33 @@ module.exports = {
// Don't precache sourcemaps (they're large) and build asset manifest:
staticFileGlobsIgnorePatterns: [/\.map$/, /asset-manifest\.json$/],
}),
// Moment.js is an extremely popular library that bundles large locale files
// by default due to how Webpack interprets its code. This is a practical
// solution that requires the user to opt into importing specific locales.
// https://github.com/jmblog/how-to-optimize-momentjs-with-webpack
// You can remove this if you don't use Moment.js:
new webpack.IgnorePlugin(/^\.\/locale$/, /moment$/),
],
optimization: {
minimize: false,
// minimizer: [
// new TerserPlugin({
// cache: true,
// parallel: true,
// terserOptions: {
// compress: {
// warnings: false,
// // Disabled because of an issue with Uglify breaking seemingly valid code:
// // https://github.com/facebookincubator/create-react-app/issues/2376
// // Pending further investigation:
// // https://github.com/mishoo/UglifyJS2/issues/2011
// comparisons: false,
// },
// output: {
// comments: false,
// // Turned on because emoji and regex is not minified properly using default
// // https://github.com/facebookincubator/create-react-app/issues/2488
// ascii_only: true,
// },
// sourceMap: shouldUseSourceMap
// }
// })
// ],
},
// Some libraries import Node modules but don't use them in the browser.
// Tell Webpack to provide empty mocks for them so importing them works.
node: {
......
......@@ -3,72 +3,78 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@types/react": "^16.4.14",
"@zendeskgarden/css-avatars": "^3.0.8",
"@zendeskgarden/react-avatars": "^3.0.14",
"@zendeskgarden/react-buttons": "^3.6.2",
"@zendeskgarden/react-chrome": "^4.2.7",
"@zendeskgarden/react-grid": "^1.1.11",
"@zendeskgarden/react-menus": "^3.6.5",
"@zendeskgarden/react-theming": "^3.1.3",
"@zendeskgarden/react-typography": "^0.2.0",
"@babel/core": "7.1.2",
"@babel/runtime": "7.1.2",
"@types/node": "10.10.1",
"@types/react": "16.4.14",
"@zendeskgarden/css-avatars": "3.0.8",
"@zendeskgarden/react-avatars": "3.0.14",
"@zendeskgarden/react-buttons": "3.6.2",
"@zendeskgarden/react-chrome": "4.2.7",
"@zendeskgarden/react-grid": "1.1.11",
"@zendeskgarden/react-menus": "3.6.5",
"@zendeskgarden/react-theming": "3.1.3",
"@zendeskgarden/react-typography": "0.2.0",
"autoprefixer": "7.1.6",
"awesome-typescript-loader": "3.5.0",
"babel-core": "6.26.0",
"awesome-typescript-loader": "5.2.1",
"babel-eslint": "7.2.3",
"babel-jest": "20.0.3",
"babel-loader": "7.1.2",
"babel-preset-react-app": "^3.1.2",
"babel-runtime": "6.26.0",
"case-sensitive-paths-webpack-plugin": "2.1.1",
"babel-preset-react-app": "3.1.2",
"case-sensitive-paths-webpack-plugin": "2.1.2",
"chalk": "1.1.3",
"css-loader": "0.28.7",
"css-loader": "1.0.0",
"dotenv": "4.0.0",
"dotenv-expand": "4.2.0",
"eslint": "4.10.0",
"eslint-config-react-app": "^2.1.0",
"eslint-loader": "1.9.0",
"eslint-config-react-app": "2.1.0",
"eslint-loader": "2.1.1",
"eslint-plugin-flowtype": "2.50.1",
"eslint-plugin-import": "2.8.0",
"eslint-plugin-jsx-a11y": "5.1.1",
"eslint-plugin-react": "7.4.0",
"extract-text-webpack-plugin": "3.0.2",
"file-loader": "1.1.5",
"file-loader": "2.0.0",
"fs-extra": "3.0.1",
"html-webpack-plugin": "2.29.0",
"husky": "^0.14.3",
"html-webpack-plugin": "3.2.0",
"husky": "0.14.3",
"interpolate-html-plugin": "3.0.0",
"jest": "20.0.4",
"lint-staged": "^7.3.0",
"lint-staged": "7.3.0",
"mini-css-extract-plugin": "0.4.3",
"object-assign": "4.1.1",
"postcss-flexbugs-fixes": "3.2.0",
"postcss-loader": "2.0.8",
"prettier": "^1.14.3",
"postcss-loader": "3.0.0",
"prettier": "1.14.3",
"promise": "8.0.1",
"raf": "3.4.0",
"react": "^16.5.2",
"react-dev-utils": "^5.0.2",
"react-dom": "^16.5.2",
"react-styleguidist": "^7.3.8",
"react": "16.5.2",
"react-dev-utils": "6.0.4",
"react-dom": "16.5.2",
"react-styleguidist": "7.3.8",
"resolve": "1.6.0",
"style-loader": "0.19.0",
"styled-components": "^3.4.9",
"sw-precache-webpack-plugin": "0.11.4",
"tslib": "^1.9.3",
"url-loader": "0.6.2",
"webpack": "3.8.1",
"webpack-dev-server": "2.11.3",
"webpack-manifest-plugin": "1.3.2",
"style-loader": "0.23.1",
"styled-components": "3.4.9",
"sw-precache-webpack-plugin": "0.11.5",
"terser-webpack-plugin": "1.1.0",
"tslib": "1.9.3",
"typescript": "3.0.3",
"uglifyjs-webpack-plugin": "2.0.1",
"url-loader": "1.1.1",
"webpack": "4.20.2",
"webpack-dev-server": "3.1.9",
"webpack-manifest-plugin": "2.0.4",
"whatwg-fetch": "2.0.3"
},
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx,json,css,md}": [
"prettier --single-quote --write",
"git add"
]
"src/**/*.{js,jsx,ts,tsx,json,css,md}": [
"prettier --single-quote --write",
"git add"
]
},
"scripts": {
"start": "node scripts/start.js",
"build": "node scripts/build.js",
"precommit": "lint-staged",
"precommit": "lint-staged",
"test": "node scripts/test.js --env=jsdom",
"styleguide": "styleguidist server",
"styleguide:build": "styleguidist build"
......@@ -114,10 +120,5 @@
},
"eslintConfig": {
"extends": "react-app"
},
"devDependencies": {
"@types/node": "^10.10.1",
"eslint-plugin-flowtype": "^2.50.1",
"typescript": "^3.0.3"
}
}
import * as React from 'react';
const { Chrome, Body } = require('@zendeskgarden/react-chrome');
const { Nav } = require('../Nav/Nav');
const { Menu } = require('../Menu/Menu');
const {
CommunitiesFeatured
} = require('../../../pages/communities.featured/CommunitiesFeatured');
import '@zendeskgarden/react-chrome/dist/styles.css';
import '@zendeskgarden/react-grid/dist/styles.css';
import '@zendeskgarden/react-buttons/dist/styles.css';
......@@ -14,16 +6,27 @@ import '@zendeskgarden/react-menus/dist/styles.css';
import '@zendeskgarden/react-avatars/dist/styles.css';
import '../../../App.css';
const { ThemeProvider } = require('@zendeskgarden/react-theming');
const { Chrome, Body } = require('@zendeskgarden/react-chrome');
const { Nav } = require('../Nav/Nav');
const { Menu } = require('../Menu/Menu');
const {
CommunitiesFeatured
} = require('../../../pages/communities.featured/CommunitiesFeatured');
const { theme } = require('../../../theme');
export class App extends React.Component {
render() {
return (
<Chrome className="App">
<Nav />
<Body className="Body">
<Menu />
<CommunitiesFeatured />
</Body>
</Chrome>
<ThemeProvider theme={theme}>
<Chrome className="App">
<Nav />
<Body className="Body">
<Menu />
<CommunitiesFeatured />
</Body>
</Chrome>
</ThemeProvider>
);
}
}
import * as React from 'react';
const { ThemeProvider } = require('@zendeskgarden/react-theming');
const { Button } = require('@zendeskgarden/react-buttons');
const { defaultTheme } = require('../../../theme');
const theme = {
'buttons.button': `
background-color: '${defaultTheme.primaryColor}';
color: white;
`
};
export const MoodleButton = ({ children }) => {
return (
<ThemeProvider theme={theme}>
<Button>{children}</Button>
</ThemeProvider>
);
return <Button>{children}</Button>;
};
export const defaultTheme = {
export const vars = {
primaryColor: '#FF7500'
};
export const theme = {
'buttons.button': `
background-color: '${vars.primaryColor}';
color: white;
`
};
This diff is collapsed.
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment