Skip to content

Commit

Permalink
Add customizable version of Scope's landing page. (#2)
Browse files Browse the repository at this point in the history
* Add customizable version of Scope's landing page.

* Allow children.

* Add to exports.

* Update README.md

* Compile to ES5 before publishing.

* Run build script post-install.

* Compile to <root>/index.js

* Do not ignore src/index.js

* Do not allow webpack to use import statements.

* Do not target umd.

* Use postinstall-build

* Commit bundled js for now.

* v0.0.2

* Update README.md
  • Loading branch information
jhb188 authored Nov 27, 2016
1 parent 9d8f456 commit e532aff
Show file tree
Hide file tree
Showing 18 changed files with 2,220 additions and 587 deletions.
2 changes: 2 additions & 0 deletions .eslintignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
node_modules/
config/
16 changes: 16 additions & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,31 @@ module.exports = {
sourceType: 'module',
},
plugins: [
'flowtype',
'react',
'sorting',
],
rules: {
'arrow-body-style': ['off'],
'arrow-parens': ['error', 'always'],
'comma-dangle': [
'error',
{
arrays: 'only-multiline',
exports: 'only-multiline',
functions: 'never',
imports: 'only-multiline',
objects: 'only-multiline',
},
],
'import/extensions': ['off'],
'import/no-extraneous-dependencies': ['off'],
'import/no-unresolved': ['off'],
'indent': ['error', 4, { SwitchCase: 1 }],
'jsx-a11y/no-static-element-interactions': ['off'],
'react/forbid-prop-types': ['error', {
'forbid': ['any', 'array'],
}],
'react/jsx-boolean-value': ['error', 'always'],
'react/jsx-closing-bracket-location': ['off'],
'react/jsx-curly-spacing': [
Expand Down
3 changes: 3 additions & 0 deletions .npmignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
src/
config/
scripts/
49 changes: 49 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
# ui-beakers
Collection of common UI components to be shared throughout SellerLabs.

## Building
Include any authored modules in imports and exports in `src/index.js`. Run `npm run build` to bundle and transpile `src/index.js` to `index.js` in project root.

TODO: Prepublish scripts (the conventional solution for transpiling npm packages written in ES6) are currently unavailable for npm-installed git repositories. Transpiling/bundling with postinstall scripts requires installing `devDependencies` prior to running the build script. A better solution than committing the build file should be investigated.

### Alert
A top level component used to show alerts throughout an application.

Expand Down Expand Up @@ -101,3 +106,47 @@ const MyCustomAlert = ({ alert }) => {
return null;
};
```

### HomePage
Landing page for Seller Labs applications (originally from Scope).

#### Usage
Example from Promote-UI:
```es6
// @flow
import React from 'react';
import { HomePage } from ui-beakers;
import {
landingPageBackground,
primary1Color,
primary2Color,
primary3Color,
} from 'constants/colors';
import promoteLogo from 'images/promote-logo.png';

const Home = () => (
<HomePage
backgroundColor={ landingPageBackground }
backgroundEndColor={ primary3Color }
lineColor={ primary2Color }
logoSrc={ promoteLogo }
particleColor={ primary1Color }
ringColor={ primary1Color } />
);

export default Home;
```

#### Props
If `backgroundEndColor` is passed, the background color will be a gradient from `backgroundColor` (top) to `backgroundEndColor`. Otherwise, the entire background will be `backgroundColor`.

```
backgroundColor: PropTypes.string,
backgroundEndColor: PropTypes.string,
children: PropTypes.node,
lineColor: PropTypes.string,
logoSrc: PropTypes.string,
logoStyle: PropTypes.object,
particleColor: PropTypes.string,
ringColor: PropTypes.string,
```
7 changes: 1 addition & 6 deletions config/paths.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,11 +27,8 @@ var nodePaths = (process.env.NODE_PATH || '')
// config after eject: we're in ./config/
module.exports = {
appBuild: resolveApp('build'),
appPublic: resolveApp('public'),
appHtml: resolveApp('public/index.html'),
appIndexJs: resolveApp('src/index.js'),
appIndexJs: resolveApp('index.js'),
appPackageJson: resolveApp('package.json'),
appSrc: resolveApp('src'),
testsSetup: resolveApp('src/setupTests.js'),
appNodeModules: resolveApp('node_modules'),
ownNodeModules: resolveApp('node_modules'),
Expand All @@ -44,8 +41,6 @@ module.exports = {
if (__dirname.indexOf(path.join('packages', 'react-scripts', 'config')) !== -1) {
module.exports = {
appBuild: resolveOwn('../../../build'),
appPublic: resolveOwn('../template/public'),
appHtml: resolveOwn('../template/public/index.html'),
appIndexJs: resolveOwn('../template/src/index.js'),
appPackageJson: resolveOwn('../package.json'),
appSrc: resolveOwn('../template/src'),
Expand Down
265 changes: 32 additions & 233 deletions config/webpack.config.prod.js
Original file line number Diff line number Diff line change
@@ -1,238 +1,37 @@
var path = require('path');
var autoprefixer = require('autoprefixer');
var webpack = require('webpack');
var HtmlWebpackPlugin = require('html-webpack-plugin');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ManifestPlugin = require('webpack-manifest-plugin');
var InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin');
var url = require('url');
var paths = require('./paths');
var getClientEnvironment = require('./env');

function ensureSlash(path, needsSlash) {
var hasSlash = path.endsWith('/');
if (hasSlash && !needsSlash) {
return path.substr(path, path.length - 1);
} else if (!hasSlash && needsSlash) {
return path + '/';
} else {
return path;
}
}

// We use "homepage" field to infer "public path" at which the app is served.
// Webpack needs to know it to put the right <script> hrefs into HTML even in
// single-page apps that may serve index.html for nested URLs like /todos/42.
// We can't use a relative path in HTML because we don't want to load something
// like /todos/42/static/js/bundle.7289d.js. We have to know the root.
var homepagePath = require(paths.appPackageJson).homepage;
var homepagePathname = homepagePath ? url.parse(homepagePath).pathname : '/';
// 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.
var publicPath = ensureSlash(homepagePathname, true);
// `publicUrl` is just like `publicPath`, but we will provide it to our app
// as %PUBLIC_URL% in `index.html` and `process.env.PUBLIC_URL` in JavaScript.
// Omit trailing slash as %PUBLIC_PATH%/xyz looks better than %PUBLIC_PATH%xyz.
var publicUrl = ensureSlash(homepagePathname, false);
// Get environment variables to inject into our app.
var env = getClientEnvironment(publicUrl);

// Assert this just to be safe.
// Development builds of React are slow and not intended for production.
if (env['process.env'].NODE_ENV !== '"production"') {
throw new Error('Production builds must have NODE_ENV=production.');
}
var path = require('path');
var libraryName = 'ui-beakers';
var nodeExternals = require('webpack-node-externals');

// 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.
module.exports = {
// Don't attempt to continue if there are any errors.
bail: true,
// We generate sourcemaps in production. This is slow but gives good results.
// You can exclude the *.map files from the build during deployment.
devtool: 'source-map',
// In production, we only want to load the polyfills and the app code.
entry: [
require.resolve('./polyfills'),
paths.appIndexJs
],
output: {
// The build folder.
path: paths.appBuild,
// Generated JS file names (with nested folders).
// There will be one main bundle, and one file per asynchronous chunk.
// We don't currently advertise code splitting but Webpack supports it.
filename: 'static/js/[name].[chunkhash:8].js',
chunkFilename: 'static/js/[name].[chunkhash:8].chunk.js',
// We inferred the "public path" (such as / or /my-project) from homepage.
publicPath: publicPath
},
resolve: {
// This allows you to set a fallback for where Webpack should look for modules.
// We read `NODE_PATH` environment variable in `paths.js` and pass paths here.
// We use `fallback` instead of `root` because we want `node_modules` to "win"
// if there any conflicts. This matches Node resolution mechanism.
// https://github.com/facebookincubator/create-react-app/issues/253
fallback: paths.nodePaths,
// These are the reasonable defaults supported by the Node ecosystem.
// We also include JSX as a common component filename extension to support
// some tools, although we do not recommend using it, see:
// https://github.com/facebookincubator/create-react-app/issues/290
extensions: ['.js', '.json', '.jsx', ''],
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'
}
},

module: {
// First, run the linter.
// It's important to do this before Babel processes the JS.
preLoaders: [
{
test: /\.(js|jsx)$/,
loader: 'eslint',
include: paths.appSrc
}
entry: path.resolve('./src/index.js'),
externals: [nodeExternals()],
devtool: 'source-map',
output: {
path: path.resolve(),
filename: 'index.js',
library: libraryName,
libraryTarget: 'umd',
},
module: {
loaders: [
{
test: /(\.jsx|\.js)$/,
loader: 'babel',
exclude: /node_modules/,
},
{
test: /(\.jsx|\.js)$/,
loader: "eslint-loader",
exclude: /node_modules/,
},
],
},
plugins: [
webpack.optimize.UglifyJsPlugin,
],
loaders: [
// Process JS with Babel.
{
test: /\.(js|jsx)$/,
include: paths.appSrc,
loader: 'babel',

},
// The notation here is somewhat confusing.
// "postcss" loader applies autoprefixer to our CSS.
// "css" loader resolves paths in CSS and adds assets as dependencies.
// "style" loader normally turns CSS into JS modules injecting <style>,
// but unlike in development configuration, we do something different.
// `ExtractTextPlugin` first applies the "postcss" and "css" loaders
// (second argument), then grabs the result CSS and puts it into a
// separate file in our build process. This way we actually ship
// a single CSS file in production instead of JS code injecting <style>
// tags. If you use code splitting, however, any async bundles will still
// use the "style" loader inside the async code so CSS from them won't be
// in the main CSS file.
{
test: /\.css$/,
// "?-autoprefixer" disables autoprefixer in css-loader itself:
// https://github.com/webpack/css-loader/issues/281
// We already have it thanks to postcss. We only pass this flag in
// production because "css" loader only enables autoprefixer-powered
// removal of unnecessary prefixes when Uglify plugin is enabled.
// Webpack 1.x uses Uglify plugin as a signal to minify *all* the assets
// including CSS. This is confusing and will be removed in Webpack 2:
// https://github.com/webpack/webpack/issues/283
loader: ExtractTextPlugin.extract('style', 'css?importLoaders=1&-autoprefixer!postcss')
// Note: this won't work without `new ExtractTextPlugin()` in `plugins`.
},
// JSON is not enabled by default in Webpack but both Node and Browserify
// allow it implicitly so we also enable it.
{
test: /\.json$/,
loader: 'json'
},
// "file" loader makes sure those assets end up in the `build` folder.
// When you `import` an asset, you get its filename.
{
test: /\.(ico|jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2)(\?.*)?$/,
loader: 'file',
query: {
name: 'static/media/[name].[hash:8].[ext]'
}
},
// "url" loader works just like "file" loader but it also embeds
// assets smaller than specified size as data URLs to avoid requests.
{
test: /\.(mp4|webm|wav|mp3|m4a|aac|oga)(\?.*)?$/,
loader: 'url',
query: {
limit: 10000,
name: 'static/media/[name].[hash:8].[ext]'
}
}
]
},

// We use PostCSS for autoprefixing only.
postcss: function() {
return [
autoprefixer({
browsers: [
'>1%',
'last 4 versions',
'Firefox ESR',
'not ie < 9', // React doesn't support IE8 anyway
]
}),
];
},
plugins: [
// Makes the public URL 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({
PUBLIC_URL: publicUrl
}),
// Generates an `index.html` file with the <script> injected.
new HtmlWebpackPlugin({
inject: true,
template: paths.appHtml,
minify: {
removeComments: true,
collapseWhitespace: true,
removeRedundantAttributes: true,
useShortDoctype: true,
removeEmptyAttributes: true,
removeStyleLinkTypeAttributes: true,
keepClosingSlash: true,
minifyJS: true,
minifyCSS: true,
minifyURLs: true
}
}),
// 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),
// This helps ensure the builds are consistent if source hasn't changed:
new webpack.optimize.OccurrenceOrderPlugin(),
// Try to dedupe duplicated modules, if any:
new webpack.optimize.DedupePlugin(),
// Minify the code.
new webpack.optimize.UglifyJsPlugin({
compress: {
screw_ie8: true, // React doesn't support IE8
warnings: false
},
mangle: {
screw_ie8: true
},
output: {
comments: false,
screw_ie8: true
}
}),
// Note: this won't work without ExtractTextPlugin.extract(..) in `loaders`.
new ExtractTextPlugin('static/css/[name].[contenthash:8].css'),
// 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
// having to parse `index.html`.
new ManifestPlugin({
fileName: 'asset-manifest.json'
})
],
// 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: {
fs: 'empty',
net: 'empty',
tls: 'empty'
}
resolve: {
root: path.resolve('./src'),
extensions: ['', '.js'],
},
};
Loading

0 comments on commit e532aff

Please sign in to comment.