diff --git a/components/x-increment/package.json b/components/x-increment/package.json index 1bc39e9c9..e85cad9df 100644 --- a/components/x-increment/package.json +++ b/components/x-increment/package.json @@ -5,8 +5,7 @@ "main": "dist/Increment.cjs.js", "scripts": { "postinstall": "npm run build", - "build": "rollup -c rollup.config.js", - "start": "rollup --watch -c rollup.config.js" + "build": "node rollup.js" }, "keywords": [], "author": "", @@ -14,8 +13,7 @@ "browser": "dist/Increment.es5.js", "module": "dist/Increment.esm.js", "devDependencies": { - "@financial-times/x-rollup": "file:../../packages/x-rollup", - "rollup": "^0.57.1" + "@financial-times/x-rollup": "file:../../packages/x-rollup" }, "dependencies": { "@financial-times/x-engine": "file:../../packages/x-engine", diff --git a/components/x-increment/rollup.config.js b/components/x-increment/rollup.config.js deleted file mode 100644 index d28cf113c..000000000 --- a/components/x-increment/rollup.config.js +++ /dev/null @@ -1,6 +0,0 @@ -import xRollup from '@financial-times/x-rollup'; -import pkg from './package.json'; - -const input = 'src/Increment.jsx'; - -export default xRollup({input, pkg, external: ['@financial-times/x-interaction']}); diff --git a/components/x-increment/rollup.js b/components/x-increment/rollup.js new file mode 100644 index 000000000..e29c5583b --- /dev/null +++ b/components/x-increment/rollup.js @@ -0,0 +1,4 @@ +const xRollup = require('@financial-times/x-rollup'); +const pkg = require('./package.json'); + +xRollup({ input: './src/Increment.jsx', pkg }); diff --git a/components/x-interaction/package.json b/components/x-interaction/package.json index 6bd57ae7e..960718757 100644 --- a/components/x-interaction/package.json +++ b/components/x-interaction/package.json @@ -5,8 +5,7 @@ "main": "dist/Interaction.cjs.js", "scripts": { "postinstall": "npm run build", - "build": "rollup -c rollup.config.js", - "start": "rollup --watch -c rollup.config.js" + "build": "node rollup.js" }, "keywords": [], "author": "", @@ -14,8 +13,7 @@ "browser": "dist/Interaction.es5.js", "module": "dist/Interaction.esm.js", "devDependencies": { - "@financial-times/x-rollup": "file:../../packages/x-rollup", - "rollup": "^0.57.1" + "@financial-times/x-rollup": "file:../../packages/x-rollup" }, "dependencies": { "@financial-times/x-engine": "file:../../packages/x-engine", diff --git a/components/x-interaction/rollup.config.js b/components/x-interaction/rollup.config.js deleted file mode 100644 index b71b315ea..000000000 --- a/components/x-interaction/rollup.config.js +++ /dev/null @@ -1,12 +0,0 @@ -import xRollup from '@financial-times/x-rollup'; -import pkg from './package.json'; - -const input = 'src/Interaction.jsx'; - -export default xRollup({ - input, - pkg, - external: [ - '@quarterto/short-id', - ] -}); diff --git a/components/x-interaction/rollup.js b/components/x-interaction/rollup.js new file mode 100644 index 000000000..922d28e45 --- /dev/null +++ b/components/x-interaction/rollup.js @@ -0,0 +1,4 @@ +const xRollup = require('@financial-times/x-rollup'); +const pkg = require('./package.json'); + +xRollup({ input: './src/Interaction.jsx', pkg }); diff --git a/components/x-styling-demo/package.json b/components/x-styling-demo/package.json index 65809d6c7..6bcc91720 100644 --- a/components/x-styling-demo/package.json +++ b/components/x-styling-demo/package.json @@ -9,16 +9,14 @@ "private": true, "scripts": { "postinstall": "npm run build", - "build": "rollup -c rollup.config.js", - "start": "rollup --watch -c rollup.config.js" + "build": "node rollup.js" }, "keywords": [], "author": "", "license": "ISC", "devDependencies": { "@financial-times/x-rollup": "file:../../packages/x-rollup", - "node-sass": "^4.9.0", - "rollup": "^0.57.1" + "node-sass": "^4.9.0" }, "dependencies": { "@financial-times/x-engine": "file:../../packages/x-engine", diff --git a/components/x-styling-demo/rollup.config.js b/components/x-styling-demo/rollup.config.js deleted file mode 100644 index 711f0559c..000000000 --- a/components/x-styling-demo/rollup.config.js +++ /dev/null @@ -1,6 +0,0 @@ -import xRollup from '@financial-times/x-rollup'; -import pkg from './package.json'; - -const input = 'src/Button.jsx'; - -export default xRollup({ input, pkg, external: ['classnames'] }); diff --git a/components/x-styling-demo/rollup.js b/components/x-styling-demo/rollup.js new file mode 100644 index 000000000..ffd6fd551 --- /dev/null +++ b/components/x-styling-demo/rollup.js @@ -0,0 +1,4 @@ +const xRollup = require('@financial-times/x-rollup'); +const pkg = require('./package.json'); + +xRollup({ input: './src/Button.jsx', pkg }); diff --git a/components/x-teaser/package.json b/components/x-teaser/package.json index ebcfa4cd6..8bfcb9777 100644 --- a/components/x-teaser/package.json +++ b/components/x-teaser/package.json @@ -8,8 +8,7 @@ "types": "Props.d.ts", "scripts": { "postinstall": "npm run build", - "build": "rollup -c rollup.config.js", - "start": "rollup --watch -c rollup.config.js" + "build": "node rollup.js" }, "keywords": [], "author": "", @@ -19,8 +18,7 @@ "dateformat": "^3.0.3" }, "devDependencies": { - "@financial-times/x-rollup": "file:../../packages/x-rollup", - "rollup": "^0.57.1" + "@financial-times/x-rollup": "file:../../packages/x-rollup" }, "engines": { "node": ">= 6.0.0" diff --git a/components/x-teaser/rollup.config.js b/components/x-teaser/rollup.config.js deleted file mode 100644 index 759527f67..000000000 --- a/components/x-teaser/rollup.config.js +++ /dev/null @@ -1,10 +0,0 @@ -import xRollup from '@financial-times/x-rollup'; -import pkg from './package.json'; - -const input = 'src/Teaser.jsx'; - -const external = [ - 'dateformat' -]; - -export default xRollup({input, pkg, external}); diff --git a/components/x-teaser/rollup.js b/components/x-teaser/rollup.js new file mode 100644 index 000000000..6bd63c6aa --- /dev/null +++ b/components/x-teaser/rollup.js @@ -0,0 +1,4 @@ +const xRollup = require('@financial-times/x-rollup'); +const pkg = require('./package.json'); + +xRollup({ input: './src/Teaser.jsx', pkg }); diff --git a/packages/x-rollup/index.js b/packages/x-rollup/index.js index 5a617f614..0b947898f 100644 --- a/packages/x-rollup/index.js +++ b/packages/x-rollup/index.js @@ -1,101 +1,19 @@ -const babel = require('rollup-plugin-babel'); -const commonjs = require('rollup-plugin-commonjs'); -const postcss = require('rollup-plugin-postcss'); -const path = require('path'); +/* eslint no-console:off */ -const resolvePlugin = (plugin) => Array.isArray(plugin) - ? [require.resolve(plugin[0]), plugin[1]] - : require.resolve(plugin); +const rollup = require('rollup'); +const rollupConfig = require('./src/rollup-config'); -const babelOptions = (targets) => ({ - include: '**/*.{js,jsx}', - plugins: [ - ['babel-plugin-transform-react-jsx', { - pragma: 'h', - useBuiltIns: true, - }], - ['babel-plugin-transform-object-rest-spread', { - // although this is stage 4, we'd have to use babel 7 to get the version - // of preset-env that supports it :/ - useBuiltIns: true, - }], - 'babel-plugin-external-helpers', - ['fast-async', { - compiler: { - noRuntime: true, - }, - }], - ].map(resolvePlugin), +module.exports = async (options) => { + const config = rollupConfig(options); - presets: targets && [ - ['babel-preset-env', { - targets, - modules: false, - exclude: ['transform-regenerator', 'transform-async-to-generator'], - }], - ].map(resolvePlugin), -}); - -module.exports = ({input, pkg, external: extraExternal = []}) => { - const external = [ - '@financial-times/x-engine', - ...extraExternal, - ]; - - const commonPlugin = commonjs({ extensions: ['.js', '.jsx'] }); - const postcssPlugin = pkg.style && postcss({ - extract: pkg.style, - modules: true, - use: [ - ['sass', { - includePaths: [path.resolve(process.cwd(), 'bower_components')] - }], - 'stylus', - 'less', - ], - }); - - return [ - { - input, - output: { - file: pkg.module, - format: 'es' - }, - external, - plugins: [ - babel(babelOptions({ node: 6 })), - postcssPlugin, - commonPlugin - ].filter(Boolean), - }, - { - input, - output: { - file: pkg.main, - format: 'cjs' - }, - external, - plugins: [ - babel(babelOptions({ node: 6 })), - postcssPlugin, - commonPlugin, - ].filter(Boolean), - }, - { - input, - output: { - file: pkg.browser, - format: 'cjs' - }, - external, - plugins: [ - babel(babelOptions({ browsers: ['ie 11'] })), - postcssPlugin, - commonPlugin, - ].filter(Boolean), + for (const [input, output] of config) { + try { + console.log(`Bundling ${input.input} ➡ ${output.file}…`); + const bundle = await rollup.rollup(input); + await bundle.write(output); + } catch (error) { + console.error(error); + process.exit(1); } - ]; + } }; - -module.exports.babelOptions = babelOptions; diff --git a/packages/x-rollup/package.json b/packages/x-rollup/package.json index 0045b55b3..230c45eb5 100644 --- a/packages/x-rollup/package.json +++ b/packages/x-rollup/package.json @@ -16,11 +16,9 @@ "babel-plugin-transform-react-jsx": "^6.24.1", "babel-preset-env": "^1.7.0", "fast-async": "^6.3.7", + "rollup": "^0.63.0", "rollup-plugin-babel": "^3.0.7", "rollup-plugin-commonjs": "^9.1.3", "rollup-plugin-postcss": "^1.6.2" - }, - "peerDependencies": { - "rollup": "^0.57.1" } } diff --git a/packages/x-rollup/rollup.template.js b/packages/x-rollup/rollup.template.js deleted file mode 100644 index 183e48c73..000000000 --- a/packages/x-rollup/rollup.template.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = name => `import xRollup from '@financial-times/x-rollup'; -import pkg from './package.json'; - -const input = 'src/${name}.jsx'; - -export default xRollup({input, pkg}); -`; diff --git a/packages/x-rollup/src/babel-config.js b/packages/x-rollup/src/babel-config.js new file mode 100644 index 000000000..424d3bfbc --- /dev/null +++ b/packages/x-rollup/src/babel-config.js @@ -0,0 +1,43 @@ +module.exports = (targets = []) => ({ + include: '**/*.{js,jsx}', + plugins: [ + // this plugin is not React specific! It includes a general JSX parser and helper 🙄 + [ + require.resolve('babel-plugin-transform-react-jsx'), + { + pragma: 'h', + useBuiltIns: true + } + ], + // Although this feature is at stage 4, we'd have to use babel 7 to get the version + // of preset-env that actually supports it 😖 + [ + require.resolve('babel-plugin-transform-object-rest-spread'), + { + useBuiltIns: true + } + ], + // Instruct Babel to not include any internal helper declarations in the output + require.resolve('babel-plugin-external-helpers'), + // Implements async/await using syntax transformation rather than generators which require + // a huge runtime for browsers which do not natively support them. + [ + require.resolve('fast-async'), + { + compiler: { + noRuntime: true + } + } + ] + ], + presets: [ + [ + require.resolve('babel-preset-env'), + { + targets, + modules: false, + exclude: ['transform-regenerator', 'transform-async-to-generator'] + } + ] + ] +}); diff --git a/packages/x-rollup/src/postcss-config.js b/packages/x-rollup/src/postcss-config.js new file mode 100644 index 000000000..5fac57486 --- /dev/null +++ b/packages/x-rollup/src/postcss-config.js @@ -0,0 +1,18 @@ +const path = require('path'); + +module.exports = (style) => { + return { + extract: style, + modules: true, + use: [ + [ + 'sass', + { + includePaths: [path.resolve(process.cwd(), 'bower_components')] + } + ], + 'stylus', + 'less' + ] + }; +}; diff --git a/packages/x-rollup/src/rollup-config.js b/packages/x-rollup/src/rollup-config.js new file mode 100644 index 000000000..a3b85dd67 --- /dev/null +++ b/packages/x-rollup/src/rollup-config.js @@ -0,0 +1,58 @@ +const babel = require('rollup-plugin-babel'); +const postcss = require('rollup-plugin-postcss'); +const commonjs = require('rollup-plugin-commonjs'); +const postcssConfig = require('./postcss-config'); +const babelConfig = require('./babel-config'); + +module.exports = ({ input, pkg }) => { + // Don't bundle any dependencies + const external = Object.keys(pkg.dependencies); + + const plugins = [ + // Convert CommonJS modules to ESM so they can be included in the bundle + commonjs({ extensions: ['.js', '.jsx'] }) + ]; + + // Add support for CSS modules (and any required transpilation) + if (pkg.style) { + const config = postcssConfig(pkg.style); + plugins.push(postcss(config)); + } + + // Pairs of input and output options + return [ + [ + { + input, + external, + plugins: [babel(babelConfig({ node: 6 })), ...plugins] + }, + { + file: pkg.module, + format: 'es' + } + ], + [ + { + input, + external, + plugins: [babel(babelConfig({ node: 6 })), ...plugins] + }, + { + file: pkg.main, + format: 'cjs' + } + ], + [ + { + input, + external, + plugins: [babel(babelConfig({ browsers: ['ie 11'] })), ...plugins] + }, + { + file: pkg.browser, + format: 'cjs' + } + ] + ]; +};