Skip to content

Commit

Permalink
Tweaks to support component directory bundles
Browse files Browse the repository at this point in the history
- Storybook now also finds stories in frontend/src/app/**/stories.js

- `npm run test` now also finds tests in frontend/src/app/**/tests.js

- New /static/app/app.js.css stylesheet built from Sass styles imported
  by components

- Hacks to ignore .scss imports when using component modules outside
  Webpack for static page build & tests

- Update flowconfig to ignore .scss imports

- Small eslint upgrade so CLI matches gulp-eslint

Issue mozilla#2807
  • Loading branch information
lmorchard committed Sep 15, 2017
1 parent f2f907c commit e73f2fe
Show file tree
Hide file tree
Showing 9 changed files with 72 additions and 8 deletions.
8 changes: 7 additions & 1 deletion .eslintrc
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,8 @@ rules:
comma-dangle: [2, never]
indent: [2, 2, {SwitchCase: 1}]
max-len: [0]
one-var: off
one-var-declaration-per-line: off
no-console: 1
no-multi-spaces: [0]
no-param-reassign: [0]
Expand All @@ -44,4 +46,8 @@ rules:
linebreak-style: [0]
"import/no-extraneous-dependencies":
- error
- { devDependencies: [ "./frontend/{stories,tasks,tests}/**/*.{js,jsx}" ] }
-
devDependencies:
- '**/tests.js'
- '**/stories.{js,jsx}'
- "./frontend/{stories,tasks,tests}/**/*.{js,jsx}"
2 changes: 2 additions & 0 deletions .storybook/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,11 @@ import '../frontend/build/static/styles/experiments.css';
import '../frontend/build/static/styles/main.css';

const req = require.context('../frontend/stories', true, /\-story\.jsx?$/);
const reqInSrcTree = require.context('../frontend/src/app', true, /\/stories.jsx?$/);

function loadStories() {
req.keys().forEach((filename) => req(filename));
reqInSrcTree.keys().forEach((filename) => reqInSrcTree(filename));
}

configure(loadStories, module);
23 changes: 23 additions & 0 deletions .storybook/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
const path = require('path');

// Export a function. Accept the base config as the only param.
module.exports = (storybookBaseConfig, configType) => {
// configType has a value of 'DEVELOPMENT' or 'PRODUCTION'
// You can change the configuration based on that.
// 'PRODUCTION' is used when building the static version of storybook.

// Make whatever fine-grained changes you need
storybookBaseConfig.module.rules.push({
test: /\.s?css$/,
loaders: ["style-loader", "css-loader", "sass-loader"],
include: path.resolve(__dirname, '../')
});

storybookBaseConfig.module.rules.push({
test: /\.(png|jpg|gif|svg)$/,
loaders: ['url-loader']
});

// Return the altered config
return storybookBaseConfig;
};
5 changes: 5 additions & 0 deletions frontend/.flowconfig
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,9 @@
[libs]
../flow-typed

[options]
module.file_ext=.scss
module.file_ext=.js
module.file_ext=.jsx

module.name_mapper='.*\.scss$' -> 'empty/object'
1 change: 1 addition & 0 deletions frontend/tasks/pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,7 @@ function generateStaticPage(prepareForClient, pageName, pageParam, component, {
<link rel="stylesheet" href="https://code.cdn.mozilla.net/fonts/fira.css" />
<link rel="stylesheet" href="/static/styles/experiments.css" />
<link rel="stylesheet" href="/static/styles/main.css" />
<link rel="stylesheet" href="/static/app/app.js.css" />

<meta name="defaultLanguage" content="en-US" />
<meta name="availableLanguages" content={ available_locales } />
Expand Down
3 changes: 3 additions & 0 deletions frontend/test-setup.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
// Global setup for all tests

// HACK: Ignore non-JS imports used for asset dependencies in Webpack
require.extensions['.scss'] = function () {}

// We need jsdom for enzyme mount()'ed components - mainly the sticky header
// scroll handler stuff on the experiments page.

Expand Down
3 changes: 3 additions & 0 deletions gulpfile.babel.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
/* eslint-disable import/no-extraneous-dependencies*/
require('babel-polyfill');

// HACK: Ignore non-JS imports used for asset dependencies in Webpack
require.extensions['.scss'] = function () {}

const gulp = require('gulp');
const config = require('./frontend/config.js');

Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -55,14 +55,16 @@
"cross-spawn": "^5.1.0",
"del": "2.2.2",
"doctoc": "1.3.0",
"empty": "0.10.1",
"enzyme": "2.7.1",
"eslint": "3.17.1",
"eslint": "3.19.0",
"eslint-config-airbnb": "10.0.1",
"eslint-config-react": "1.1.7",
"eslint-plugin-flowtype": "2.30.0",
"eslint-plugin-import": "2.2.0",
"eslint-plugin-jsx-a11y": "5.0.3",
"eslint-plugin-react": "7.0.1",
"extract-text-webpack-plugin": "3.0.0",
"feed": "1.1.0",
"fetch-mock": "5.9.4",
"flow-bin": "0.47.0",
Expand Down Expand Up @@ -95,11 +97,13 @@
"require-globify": "1.4.1",
"run-sequence": "1.2.2",
"sass-lint": "1.10.2",
"sass-loader": "6.0.6",
"sinon": "2.0.0",
"through2": "2.0.3",
"uglifyjs-webpack-plugin": "^0.4.6",
"url-loader": "^0.5.9",
"vinyl-source-stream": "1.1.0",
"webpack": "^3.5.5",
"webpack": "3.5.6",
"webpack-bundle-analyzer": "^2.9.0",
"webpack-stream": "^4.0.0",
"yamljs": "0.2.8"
Expand All @@ -122,11 +126,11 @@
"static": "gulp dist-build",
"docs": "doctoc README.md && doctoc addon/README.md",
"lint": "gulp scripts-lint styles-lint",
"test": "cd frontend && mocha --require babel-register --require test-setup.js --recursive",
"test": "cd frontend && mocha --require babel-register --require test-setup.js --recursive 'test' 'src/**/tests.js'",
"flow": "flow frontend",
"l10n:extract": "gulp content-extract-strings",
"l10n:check": "npm run l10n:extract && git diff-files --quiet --ignore-all-space locales && echo 'No missing strings'",
"test:ci": "cross-env NODE_ENV=test nyc mocha --recursive --reporter mocha-junit-reporter --require frontend/test-setup.js frontend/test",
"test:ci": "cross-env NODE_ENV=test nyc mocha --recursive --reporter mocha-junit-reporter --require frontend/test-setup.js frontend/test 'frontend/src/**/tests.js'",
"test:watch": "npm test -- --watch",
"test:all": "npm run lint && npm run flow && npm run test && npm run flow-coverage && cd addon && npm run lint && npm run test && tox -e ui-tests",
"coverage": "cross-env NODE_ENV=test nyc mocha --recursive --require frontend/test-setup.js frontend/test",
Expand Down
23 changes: 20 additions & 3 deletions webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ const config = require('./frontend/config.js');

const UglifyJSPlugin = require('uglifyjs-webpack-plugin');
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const ExtractTextPlugin = require('extract-text-webpack-plugin');

const RUN_ANALYZER = !!process.env.ANALYZER;
const NODE_ENV = process.env.NODE_ENV || 'development';
Expand Down Expand Up @@ -35,6 +36,10 @@ const vendorModules = Object.keys(packageJSON.dependencies)
.filter(name => excludeVendorModules.indexOf(name) < 0)
.concat(includeVendorModules);

const extractSass = new ExtractTextPlugin({
filename: '[name].css'
});

const plugins = [
new webpack.DefinePlugin({
'process.env.NODE_ENV': `"${NODE_ENV}"`,
Expand All @@ -46,7 +51,8 @@ const plugins = [
/moment[\/\\]locale$/, // eslint-disable-line no-useless-escape
new RegExp(config.AVAILABLE_LOCALES.replace(/,/g, '|'))
),
new webpack.optimize.CommonsChunkPlugin('static/app/vendor.js')
new webpack.optimize.CommonsChunkPlugin('static/app/vendor.js'),
extractSass
];

if (!IS_DEV) {
Expand Down Expand Up @@ -91,12 +97,23 @@ module.exports = {
contentBase: 'dist'
},
devtool: 'source-map',
resolve: {
extensions: ['.js', '.jsx']
},
module: {
loaders: [
rules: [
{
test: /\.jsx?$/,
exclude: /node_modules/,
loader: 'babel-loader'
use: 'babel-loader'
},
{
test: /\.scss$/,
use: extractSass.extract({
use: [{ loader: 'css-loader' }, { loader: 'sass-loader' }],
// use style-loader in development
fallback: 'style-loader'
})
}
]
},
Expand Down

0 comments on commit e73f2fe

Please sign in to comment.