diff --git a/.changeset/9619af8b/changes.json b/.changeset/9619af8b/changes.json new file mode 100644 index 0000000..0c9990d --- /dev/null +++ b/.changeset/9619af8b/changes.json @@ -0,0 +1,4 @@ +{ + "releases": [{ "name": "@brisk-docs/website", "type": "patch" }], + "dependents": [] +} diff --git a/.changeset/9619af8b/changes.md b/.changeset/9619af8b/changes.md new file mode 100644 index 0000000..85f46f4 --- /dev/null +++ b/.changeset/9619af8b/changes.md @@ -0,0 +1 @@ +- sodjfsdfds \ No newline at end of file diff --git a/default.webpack.config.js b/default.webpack.config.js deleted file mode 100644 index 841d67e..0000000 --- a/default.webpack.config.js +++ /dev/null @@ -1,18 +0,0 @@ -module.exports = { - mode: 'development', - resolve: { - extensions: ['.ts', '.tsx', '.js', 'jsx'], - }, - module: { - rules: [ - { - test: /\.(ts|tsx|js|jsx)$/, - exclude: /node_modules/, - loader: 'babel-loader', - options: { - root: __dirname, - }, - }, - ], - }, -}; diff --git a/docs.config.js b/docs.config.js index 3357b34..998a90c 100644 --- a/docs.config.js +++ b/docs.config.js @@ -1,9 +1,26 @@ -const defaultWebpackConfig = require('./default.webpack.config'); +const test = file => { + const nextServerFiles = new RegExp(`^${__dirname}/packages/website/`); + const sourceFiles = /\.(ts|tsx|js|jsx)$/; + return file.match(sourceFiles) && !file.match(nextServerFiles); +}; + +const webpack = config => { + config.module.rules.push({ + test, + exclude: /node_modules/, + loader: 'babel-loader', + options: { + root: __dirname, + }, + }); + config.resolve.extensions.push('.ts', '.tsx'); + return config; +}; module.exports = () => ({ docs: './packages/website/docs', packages: ['./packages/*'], useManifests: false, - webpackConfiguration: defaultWebpackConfig, + webpack, siteName: 'Brisk Docs Docs', }); diff --git a/package.json b/package.json index af0068b..44eb92f 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "delete:dist": "bolt ws exec --parallel -- rm -rf dist", "delete:modules": "bolt ws exec --parallel -- rm -rf node_modules && rm -rf node_modules", "docs": "node packages/website/bin/index.js dev", - "start": "bolt w @brisk-docs/website run start -p 8080", + "start": "bolt w @brisk-docs/website run start", "prettier": "prettier --write \"**/*.js\"", "lint:prettier": "prettier --list-different \"**/*.js\"", "lint:eslint": "yarn eslint .", @@ -83,6 +83,7 @@ "lodash.capitalize": "^4.2.1", "lodash.debounce": "^4.0.8", "lodash.flatmap": "^4.5.0", + "lodash.identity": "^3.0.0", "lodash.snakecase": "^4.1.1", "next": "^7.0.2", "outdent": "^0.7.0", diff --git a/packages/website/__fixtures__/custom-babel-project/docs.config.js b/packages/website/__fixtures__/custom-babel-project/docs.config.js index acd994b..62e1546 100644 --- a/packages/website/__fixtures__/custom-babel-project/docs.config.js +++ b/packages/website/__fixtures__/custom-babel-project/docs.config.js @@ -1,9 +1,22 @@ const path = require('path'); -const webpackConfiguration = require('./webpack.config'); + +const webpack = config => { + config.module.rules.push({ + test: new RegExp(`${__dirname}/.*\\.(js|jsx)$`), + exclude: /node_modules/, + use: { + loader: 'babel-loader', + options: { + root: __dirname, + }, + }, + }); + return config; +}; module.exports = () => ({ packages: path.join(__dirname, 'weird-babel-package'), docs: path.join(__dirname, 'docs'), siteName: 'Babel/webpack Test Docs', - webpackConfiguration, + webpack, }); diff --git a/packages/website/__fixtures__/custom-babel-project/webpack.config.js b/packages/website/__fixtures__/custom-babel-project/webpack.config.js deleted file mode 100644 index 2a6755d..0000000 --- a/packages/website/__fixtures__/custom-babel-project/webpack.config.js +++ /dev/null @@ -1,17 +0,0 @@ -module.exports = { - mode: 'development', - module: { - rules: [ - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - root: __dirname, - }, - }, - }, - ], - }, -}; diff --git a/packages/website/__fixtures__/custom-webpack-project/docs.config.js b/packages/website/__fixtures__/custom-webpack-project/docs.config.js index 15e7d10..61e5442 100644 --- a/packages/website/__fixtures__/custom-webpack-project/docs.config.js +++ b/packages/website/__fixtures__/custom-webpack-project/docs.config.js @@ -1,9 +1,14 @@ const path = require('path'); -const webpackConfiguration = require('./webpack.config'); + +const webpack = config => { + config.resolve.modules.push(path.join(__dirname, 'packages')); + + return config; +}; module.exports = () => ({ packages: path.join(__dirname, 'packages', '*'), docs: path.join(__dirname, 'docs'), siteName: 'Webpack Test Docs', - webpackConfiguration, + webpack, }); diff --git a/packages/website/__fixtures__/custom-webpack-project/webpack.config.js b/packages/website/__fixtures__/custom-webpack-project/webpack.config.js deleted file mode 100644 index 0beaaa9..0000000 --- a/packages/website/__fixtures__/custom-webpack-project/webpack.config.js +++ /dev/null @@ -1,19 +0,0 @@ -const path = require('path'); - -module.exports = { - mode: 'development', - module: { - rules: [ - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - }, - }, - ], - }, - resolve: { - modules: [path.join(__dirname, 'packages'), 'node_modules'], - }, -}; diff --git a/packages/website/__fixtures__/index.js b/packages/website/__fixtures__/index.js new file mode 100644 index 0000000..c1c67e1 --- /dev/null +++ b/packages/website/__fixtures__/index.js @@ -0,0 +1,5 @@ +// This utility is to reduce the need to litter usages +// of __dirname across our tests which make it hard to +// move files + +module.exports.fixturesPath = __dirname; diff --git a/packages/website/__fixtures__/typescript-project/docs.config.js b/packages/website/__fixtures__/typescript-project/docs.config.js index 683a155..b234403 100644 --- a/packages/website/__fixtures__/typescript-project/docs.config.js +++ b/packages/website/__fixtures__/typescript-project/docs.config.js @@ -1,9 +1,17 @@ const path = require('path'); -const webpackConfiguration = require('./webpack.config'); + +const webpack = config => { + config.module.rules.push({ + test: /\.tsx?$/, + loader: 'babel-loader!ts-loader', + }); + + return config; +}; module.exports = () => ({ packages: path.join(__dirname, 'typescript-package'), docs: path.join(__dirname, 'docs'), siteName: 'Typescript/webpack Test Docs', - webpackConfiguration, + webpack, }); diff --git a/packages/website/__fixtures__/typescript-project/webpack.config.js b/packages/website/__fixtures__/typescript-project/webpack.config.js deleted file mode 100644 index f9781b7..0000000 --- a/packages/website/__fixtures__/typescript-project/webpack.config.js +++ /dev/null @@ -1,19 +0,0 @@ -module.exports = { - mode: 'development', - resolve: { - // Add `.tsx` as a resolvable extension. - extensions: ['.tsx', '.js'], - }, - module: { - rules: [ - { test: /\.tsx?$/, loader: 'babel-loader!ts-loader' }, - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - }, - }, - ], - }, -}; diff --git a/packages/website/bin/generate-pages.js b/packages/website/bin/generate-pages.js index d419b37..78e0884 100644 --- a/packages/website/bin/generate-pages.js +++ b/packages/website/bin/generate-pages.js @@ -22,14 +22,12 @@ module.exports = async ({ packageRoot, './components/page-templates', ); - const bundlesPath = path.resolve(packageRoot, './bundles'); const pagesList = await generatePages( packagesPaths, docsPath, pagesPath, componentsPath, - bundlesPath, { useManifests, webpackConfiguration, diff --git a/packages/website/bin/handle-config.js b/packages/website/bin/handle-config.js index 130ecdc..5e2b1b5 100644 --- a/packages/website/bin/handle-config.js +++ b/packages/website/bin/handle-config.js @@ -1,5 +1,6 @@ const path = require('path'); const fse = require('fs-extra'); +const identity = require('lodash.identity'); /** * Validates a config entry specifying a path or paths and normalises @@ -20,29 +21,11 @@ const resolvePathsConfig = entry => { throw new Error('entry must be an array or a string'); }; -const defaultWebpackConfig = { - mode: 'development', - module: { - rules: [ - { - test: /\.(js|jsx)$/, - exclude: /node_modules/, - use: { - loader: 'babel-loader', - options: { - presets: ['@babel/preset-env', '@babel/preset-react'], - }, - }, - }, - ], - }, -}; - const defaultConfig = { docs: './docs', packages: ['./packages/*'], useManifests: false, - webpackConfiguration: defaultWebpackConfig, + webpack: identity, }; /** @@ -61,13 +44,13 @@ const processConfig = (cwd, providedConfig = {}) => { path.resolve(cwd, packagesPath), ); - const { useManifests, webpackConfiguration } = config; + const { useManifests, webpack } = config; return { docsPath, packagesPaths, useManifests, - webpackConfiguration, + webpack, }; }; diff --git a/packages/website/bin/handle-config.test.js b/packages/website/bin/handle-config.test.js index 575ae44..6db3600 100644 --- a/packages/website/bin/handle-config.test.js +++ b/packages/website/bin/handle-config.test.js @@ -11,7 +11,7 @@ describe('website configuration processor', () => { packagesPaths: ['/c/w/d/packages/*'], docsPath: '/c/w/d/docs', useManifests: false, - webpackConfiguration: expect.anything(), + webpack: expect.any(Function), }); }); @@ -43,6 +43,13 @@ describe('website configuration processor', () => { expect(config.useManifests).toEqual(true); }); + + it('accepts a webpack function', () => { + const dummyWebpack = _ => _; + + const config = processConfig(mockCwd, { webpack: dummyWebpack }); + expect(config.webpack).toBe(dummyWebpack); + }); }); describe('loadConfig', () => { diff --git a/packages/website/bin/index.js b/packages/website/bin/index.js index e9ccc0c..047863b 100755 --- a/packages/website/bin/index.js +++ b/packages/website/bin/index.js @@ -1,55 +1,40 @@ #!/usr/bin/env node -const { spawnSync } = require('child_process'); -const path = require('path'); const commandLineArgs = require('command-line-args'); -const generatePages = require('./generate-pages'); -const handleConfig = require('./handle-config'); +const { dev, build, start } = require('./run-website'); const mainDefinitions = [{ name: 'command', defaultOption: true }]; const mainOptions = commandLineArgs(mainDefinitions, { stopAtFirstUnknown: true, }); -const nextRoot = path.resolve(__dirname, '..'); - // We have no control over this dangling underscore // eslint-disable-next-line no-underscore-dangle const argv = mainOptions._unknown || []; const cliOptions = [{ name: 'config', type: String }]; const options = commandLineArgs(cliOptions, { argv, camelCase: true }); -const cwd = process.cwd(); -const spawnNextProcess = command => { - spawnSync( - `PATH=$(npm bin):$PATH; NODE_PATH=$NODE_PATH:$PWD/src next ${command}`, - [], - { - stdio: 'inherit', - shell: true, - env: { ...process.env, FORCE_EXTRACT_REACT_TYPES: true }, - cwd: nextRoot, - }, - ); -}; +if (mainOptions.command === undefined) { + throw new Error(`No command supplied`); +} -const preNextScripts = async () => { - const config = handleConfig(cwd, options.config); - await generatePages(config); +const handleError = err => { + console.error(err); + process.exit(1); }; switch (mainOptions.command) { case 'dev': { - preNextScripts().then(() => spawnNextProcess('dev')); + dev(options.config).catch(handleError); break; } case 'build': { - preNextScripts().then(() => spawnNextProcess('build')); + build(options.config).catch(handleError); break; } case 'start': { - spawnNextProcess('start'); + start(options.config).catch(handleError); break; } default: diff --git a/packages/website/bin/integration.test.js b/packages/website/bin/integration.test.js index 93e7c83..e3fa258 100644 --- a/packages/website/bin/integration.test.js +++ b/packages/website/bin/integration.test.js @@ -1,29 +1,35 @@ -import generatePages from './generate-pages'; -import { processConfig } from './handle-config'; +import path from 'path'; -import customWebpackConfig from '../__fixtures__/custom-webpack-project/docs.config'; -import typescriptConfig from '../__fixtures__/typescript-project/docs.config'; -import customBabelConfig from '../__fixtures__/custom-babel-project/docs.config'; +import { build } from './run-website'; -const buildWebsiteFromFixture = async config => { - const fixtureConfig = processConfig(process.cwd(), config); +import { fixturesPath } from '../__fixtures__'; - await generatePages(fixtureConfig); -}; +const customWebpackConfig = path.join( + fixturesPath, + 'custom-webpack-project/docs.config', +); +const typescriptConfig = path.join( + fixturesPath, + 'typescript-project/docs.config', +); +const customBabelConfig = path.join( + fixturesPath, + 'custom-babel-project/docs.config', +); describe('Website generation integration tests', () => { it('can build a project with a custom Webpack configuration', () => { // assert that the website builds without error - return buildWebsiteFromFixture(customWebpackConfig()); + return build(customWebpackConfig); }); it('can build a project that uses TypeScript', () => { // assert that the website builds without error - return buildWebsiteFromFixture(typescriptConfig()); + return build(typescriptConfig); }); it('can build a project that uses a special Babel config', () => { // assert that the website builds without error - return buildWebsiteFromFixture(customBabelConfig()); + return build(customBabelConfig); }); }); diff --git a/packages/website/bin/page-generator/build-externals/README.md b/packages/website/bin/page-generator/build-externals/README.md deleted file mode 100644 index 1f6fca6..0000000 --- a/packages/website/bin/page-generator/build-externals/README.md +++ /dev/null @@ -1,3 +0,0 @@ -This utility is responsible for building/bundling code from packages so that it can be -loaded inside our website as examples etc. It spawns webpack using a config provided by the consumer, -which allows us to support packages that use custom build configurations. \ No newline at end of file diff --git a/packages/website/bin/page-generator/build-externals/index.js b/packages/website/bin/page-generator/build-externals/index.js deleted file mode 100644 index 031074e..0000000 --- a/packages/website/bin/page-generator/build-externals/index.js +++ /dev/null @@ -1,59 +0,0 @@ -const path = require('path'); -const crypto = require('crypto'); -const webpack = require('webpack'); - -const createBuilder = (inputs, destinationDir, config) => { - if (inputs.length === 0) { - return { bundles: [], run: () => Promise.resolve() }; - } - const bundles = inputs.map(input => { - const basename = path.basename(input, '.js'); - const hash = crypto - .createHash('md5') - .update(input) - .digest('hex'); - const id = `${basename}_${hash}`; - - return { id, source: input, dest: path.join(destinationDir, `${id}.js`) }; - }); - - const entry = bundles.reduce( - (acc, bundle) => ({ ...acc, [bundle.id]: bundle.source }), - {}, - ); - - const output = { - filename: '[name].js', - path: destinationDir, - libraryTarget: 'commonjs2', - }; - - const compiler = webpack({ ...config, entry, output }); - - return { - bundles, - run: () => - new Promise((resolve, reject) => { - compiler.run((err, stats) => { - if (err) { - reject(err); - } - - const info = stats.toJson(); - - if (stats.hasErrors()) { - // eslint-disable-next-line no-console - console.error(info.errors); - reject(new Error('errors occurred during compilation')); - } else if (stats.hasWarnings()) { - // eslint-disable-next-line no-console - console.warn(info.warnings); - } else { - resolve(); - } - }); - }), - }; -}; - -module.exports = createBuilder; diff --git a/packages/website/bin/page-generator/build-externals/test.js b/packages/website/bin/page-generator/build-externals/test.js deleted file mode 100644 index ff6bf59..0000000 --- a/packages/website/bin/page-generator/build-externals/test.js +++ /dev/null @@ -1,123 +0,0 @@ -import webpack from 'webpack'; -import path from 'path'; -import createBuilder from '.'; - -jest.mock('webpack'); - -describe('External code builder', () => { - let mockRunCompiler; - - const inputs = ['source/a.js', 'source/b.js', 'source/c.js']; - - const mockRunStats = { - toJson: () => {}, - hasErrors: () => false, - hasWarnings: () => false, - }; - - beforeEach(() => { - jest.resetAllMocks(); - - mockRunCompiler = jest.fn(); - const mockCompiler = { run: mockRunCompiler }; - webpack.mockReturnValue(mockCompiler); - - mockRunCompiler.mockImplementation(callback => - callback(null, mockRunStats), - ); - }); - - it('returns a list of bundle definitions', () => { - const { bundles } = createBuilder(inputs, 'bundles'); - - expect(bundles).toHaveLength(3); - - const assertHasBundle = sourceName => { - expect( - bundles.find(bundle => { - return bundle.source === `source/${sourceName}.js`; - }), - ).not.toBeUndefined(); - }; - - assertHasBundle('a'); - assertHasBundle('b'); - assertHasBundle('c'); - }); - - it('defines bundle destinations in the bundles directory', () => { - const { bundles } = createBuilder(inputs, 'bundles', {}); - - const assertHasDest = sourceName => { - const bundle = bundles.find(b => b.source === `source/${sourceName}.js`); - - expect(path.dirname(bundle.dest)).toBe('bundles'); - expect(path.basename(bundle.dest)).toMatch( - new RegExp(`${sourceName}_[a-z0-9]*.js`), - ); - }; - - assertHasDest('a'); - assertHasDest('b'); - assertHasDest('c'); - }); - - it('generates unique destination paths', () => { - const { bundles } = createBuilder( - ['source/a/index.js', 'source/b/index.js'], - 'bundles', - {}, - ); - - expect(bundles[0].dest).not.toEqual(bundles[1].dest); - }); - - it('instantiates a webpack compiler with entries and outputs matching bundle definitions', async () => { - const { bundles, run } = createBuilder(inputs, 'bundles', {}); - - await run(); - - const webpackCall = webpack.mock.calls[0][0]; - - expect(webpackCall.output).toEqual({ - filename: '[name].js', - path: 'bundles', - libraryTarget: 'commonjs2', - }); - - const assertEntry = source => { - const bundle = bundles.find(b => b.source === source); - expect(webpackCall.entry[bundle.id]).toEqual(source); - }; - - assertEntry('source/a.js'); - assertEntry('source/b.js'); - assertEntry('source/c.js'); - - expect(mockRunCompiler).toHaveBeenCalledTimes(1); - }); - - it('returns a promise that rejects when compilation fails', () => { - mockRunCompiler.mockImplementation(callback => - callback(new Error(), mockRunStats), - ); - - return expect(createBuilder(inputs, 'bundles', {}).run()).rejects.toEqual( - expect.any(Error), - ); - }); - - it('passes provided configuration to webpack', async () => { - await createBuilder(inputs, 'bundles', { option1: true }).run(); - - expect(webpack).toHaveBeenCalledWith( - expect.objectContaining({ option1: true }), - ); - }); - - it('does not start webpack if there are no files to build', async () => { - await createBuilder([], 'bundles', { option1: true }).run(); - - expect(webpack).not.toHaveBeenCalled(); - }); -}); diff --git a/packages/website/bin/page-generator/get-package-info.js b/packages/website/bin/page-generator/get-package-info.js index 985ecb1..6f355c2 100644 --- a/packages/website/bin/page-generator/get-package-info.js +++ b/packages/website/bin/page-generator/get-package-info.js @@ -97,7 +97,7 @@ module.exports = function getPackagesInfo(packagesPatterns, options = {}) { const { useManifests } = { ...defaultOptions, ...options }; - const packagesInfo = getAllDirectories(packagesPatterns) + return getAllDirectories(packagesPatterns) .map(pkgPath => { const pkgId = path.basename(pkgPath); @@ -140,14 +140,7 @@ module.exports = function getPackagesInfo(packagesPatterns, options = {}) { docsPaths, }; - const externalSources = examplesPaths.map(example => example.path); - - return { packageData, externalSources }; + return packageData; }) .filter(_ => _); - - const packages = packagesInfo.map(p => p.packageData); - const externalSources = flatMap(packagesInfo, p => p.externalSources); - - return { packages, externalSources }; }; diff --git a/packages/website/bin/page-generator/get-package-info.test.js b/packages/website/bin/page-generator/get-package-info.test.js index fab202c..0a762a6 100644 --- a/packages/website/bin/page-generator/get-package-info.test.js +++ b/packages/website/bin/page-generator/get-package-info.test.js @@ -6,13 +6,10 @@ import getPackageInfo from './get-package-info'; describe('Get package info utility', () => { let cwd; let packageInfo; - let externalSources; beforeAll(async () => { cwd = await copyFixtureIntoTempDir(__dirname, 'simple-mock-packages'); - ({ packages: packageInfo, externalSources } = getPackageInfo([ - path.join(cwd, 'packages', '/*'), - ])); + packageInfo = getPackageInfo([path.join(cwd, 'packages', '/*')]); }); it('returns a list of packages', async () => { @@ -103,7 +100,7 @@ describe('Get package info utility', () => { }); it('can accept an array of paths', () => { - const { packages: packageInfoAlternate } = getPackageInfo([ + const packageInfoAlternate = getPackageInfo([ path.join(cwd, 'packages', 'mock-package1'), path.join(cwd, 'packages', 'mock-package2'), path.join(cwd, 'packages', 'mock-package3'), @@ -120,7 +117,7 @@ describe('Get package info utility', () => { 'mock-packages-manifests', ); - const { packages: packageInfoAlternate } = getPackageInfo( + const packageInfoAlternate = getPackageInfo( [path.join(manifestAppFixturePath, 'packages', '*')], { useManifests: true }, ); @@ -131,25 +128,4 @@ describe('Get package info utility', () => { 'wcollins', ]); }); - - it('returns a list of external sources that need to be bundled', () => { - const packagesPath = path.join(cwd, 'packages'); - const mp1ExamplePath = path.join(packagesPath, 'mock-package1', 'examples'); - const mp2ExamplePath = path.join(packagesPath, 'mock-package2', 'examples'); - const mp3ExamplePath = path.join(packagesPath, 'mock-package3', 'examples'); - - expect(externalSources).toEqual([ - path.join(mp1ExamplePath, 'example1.js'), - path.join(mp1ExamplePath, 'example2.js'), - path.join(mp1ExamplePath, 'example3.js'), - - path.join(mp2ExamplePath, 'example1.js'), - path.join(mp2ExamplePath, 'example2.js'), - path.join(mp2ExamplePath, 'example3.js'), - - path.join(mp3ExamplePath, 'example1.js'), - path.join(mp3ExamplePath, 'example2.js'), - path.join(mp3ExamplePath, 'example3.js'), - ]); - }); }); diff --git a/packages/website/bin/page-generator/index.js b/packages/website/bin/page-generator/index.js index 33e665c..ec70f63 100644 --- a/packages/website/bin/page-generator/index.js +++ b/packages/website/bin/page-generator/index.js @@ -4,7 +4,6 @@ const rimraf = require('rimraf'); const titleCase = require('title-case'); const getPackageInfo = require('./get-package-info'); const getDocsInfo = require('./get-docs-info'); -const getExternalModuleBuilder = require('./build-externals'); const { generateHomePage, generatePackageDocPage, @@ -22,7 +21,7 @@ const packagesData = []; * @param generatorConfig info about the locations of important directories used for page generation * @returns a sitemap of all the pages created */ -function generatePackagePages(packageInfo, bundlesInfo, generatorConfig) { +function generatePackagePages(packageInfo, generatorConfig) { const packageSitemap = packageInfo.map(pkg => { const pageData = { id: pkg.id, packageName: pkg.name }; const homePageData = { @@ -76,14 +75,9 @@ function generatePackagePages(packageInfo, bundlesInfo, generatorConfig) { const rawPagesPath = path.join(homePath, 'examples/isolated', example.id); const isolatedPath = path.join('/', `${rawPagesPath}`); - const exampleModulePath = bundlesInfo.find( - bundle => bundle.source === example.path, - ).dest; - generateExamplePage( `${pagePath}.js`, `${rawPagesPath}.js`, - exampleModulePath, example.path, { ...pageData, isolatedPath }, generatorConfig, @@ -194,17 +188,13 @@ module.exports = async function generatePages( docsPath, pagesPath, componentsPath, - bundlesPath, options = {}, ) { cleanPages(pagesPath); - const { packages: packageInfo, externalSources } = getPackageInfo( - packagesPaths, - { - useManifests: options.useManifests, - }, - ); + const packageInfo = getPackageInfo(packagesPaths, { + useManifests: options.useManifests, + }); const docsInfo = getDocsInfo(docsPath); const generatorConfig = { @@ -212,19 +202,7 @@ module.exports = async function generatePages( wrappersPath: componentsPath, }; - const { bundles, run: buildExternalModules } = getExternalModuleBuilder( - externalSources, - bundlesPath, - options.webpackConfiguration, - ); - - await buildExternalModules(); - - const packageSitemap = generatePackagePages( - packageInfo, - bundles, - generatorConfig, - ); + const packageSitemap = generatePackagePages(packageInfo, generatorConfig); const docsSitemap = generateProjectDocsPages(docsInfo, generatorConfig); return { diff --git a/packages/website/bin/page-generator/templates/index.js b/packages/website/bin/page-generator/templates/index.js index cb33a5e..edd4084 100644 --- a/packages/website/bin/page-generator/templates/index.js +++ b/packages/website/bin/page-generator/templates/index.js @@ -19,9 +19,9 @@ const basicPageTemplate = ( return outdent` import Wrapper from '${wrapperPath}'; import PageTitle from '${pageTitlePath}' - + export default () => ( - <> + <> @@ -33,9 +33,9 @@ const basicPageTemplate = ( import Component from '${componentPath}'; import Wrapper from '${wrapperPath}'; import PageTitle from '${pageTitlePath}' - + export default () => ( - <> + <> @@ -48,18 +48,17 @@ const basicPageTemplate = ( const exampleTemplate = ( componentPath, wrapperPath, - sourcePath, data = {}, title = '', ) => outdent` import Component from '${componentPath}'; - import fileContents from '!!raw-loader!${sourcePath}'; + import fileContents from '!!raw-loader!${componentPath}'; import Wrapper from '${wrapperPath}'; import PageTitle from '${pageTitlePath}' - + export default () => ( - <> + <> @@ -82,9 +81,9 @@ const basicNonComponentTemplate = ( ) => outdent` import Wrapper from '${wrapperPath}'; import PageTitle from '${pageTitlePath}' - + export default () => ( - <> + <> @@ -191,7 +190,6 @@ const generateExamplePage = ( pagePath, rawPagesPath, exampleModulePath, - sourceCodePath, data, config, title = '', @@ -208,18 +206,9 @@ const generateExamplePage = ( wrapperName, ); - const absolutePagePath = path.resolve(pagesPath, pagePath); - const relativeSourcePath = getImportPath(absolutePagePath, sourceCodePath); - writeFile( path.join(pagesPath, pagePath), - exampleTemplate( - componentImportPath, - packageHomeWrapperPath, - relativeSourcePath, - data, - title, - ), + exampleTemplate(componentImportPath, packageHomeWrapperPath, data, title), ); writeFile( diff --git a/packages/website/bin/page-generator/test.js b/packages/website/bin/page-generator/test.js index 61faf15..3231959 100644 --- a/packages/website/bin/page-generator/test.js +++ b/packages/website/bin/page-generator/test.js @@ -2,40 +2,8 @@ import path from 'path'; import fs from 'fs'; import { copyFixtureIntoTempDir, createTempDir } from 'jest-fixtures'; -import mockCreateBuilder from './build-externals'; import generatePages from './index'; -jest.mock('./build-externals'); - -// TODO: refactor this test suite so such a messy mock is no longer needed -const mockModuleBuilder = packagesCwd => { - const createMockBundle = (packageName, exampleName) => ({ - source: path.join( - packagesCwd, - 'packages', - packageName, - 'examples', - exampleName, - ), - dest: 'bundles/mp1-example1.js', - }); - - mockCreateBuilder.mockImplementation(() => ({ - run: () => Promise.resolve(), - bundles: [ - createMockBundle('mock-package1', 'example1.js'), - createMockBundle('mock-package1', 'example2.js'), - createMockBundle('mock-package1', 'example3.js'), - createMockBundle('mock-package2', 'example1.js'), - createMockBundle('mock-package2', 'example2.js'), - createMockBundle('mock-package2', 'example3.js'), - createMockBundle('mock-package3', 'example1.js'), - createMockBundle('mock-package3', 'example2.js'), - createMockBundle('mock-package3', 'example3.js'), - ], - })); -}; - describe('Generate pages', () => { let packagesPaths; let pagesPath; @@ -53,16 +21,12 @@ describe('Generate pages', () => { const docsPath = path.join(docsCwd, 'docs'); pagesPath = await createTempDir(); const componentsPath = await createTempDir(); - const bundlesPath = await createTempDir(); - - mockModuleBuilder(packagesCwd); sitemap = await generatePages( packagesPaths, docsPath, pagesPath, componentsPath, - bundlesPath, ); }); @@ -305,7 +269,6 @@ describe('File modification tests', () => { let docsPath; let pagesPath; let componentsPath; - let bundlesPath; beforeEach(async () => { const packagesCwd = await copyFixtureIntoTempDir( @@ -314,13 +277,10 @@ describe('File modification tests', () => { ); const docsCwd = await copyFixtureIntoTempDir(__dirname, 'simple-mock-docs'); - mockModuleBuilder(packagesCwd); - packagesPath = path.join(packagesCwd, 'packages'); docsPath = path.join(docsCwd, 'docs'); pagesPath = await createTempDir(); componentsPath = await createTempDir(); - bundlesPath = await createTempDir(); }); it('should remove files from package docs pages that are removed from disc on rerun', async () => { @@ -336,7 +296,6 @@ describe('File modification tests', () => { docsPath, pagesPath, componentsPath, - bundlesPath, ); expect(fs.existsSync(firstDocsPage)).toEqual(true); @@ -349,7 +308,6 @@ describe('File modification tests', () => { docsPath, pagesPath, componentsPath, - bundlesPath, ); expect(fs.existsSync(firstDocsPage)).toEqual(false); @@ -357,13 +315,7 @@ describe('File modification tests', () => { it('should remove files from docs pages that are removed from disc on rerun', async () => { const firstDocsPage = path.join(pagesPath, 'docs', 'doc-1.js'); - await generatePages( - packagesPath, - docsPath, - pagesPath, - componentsPath, - bundlesPath, - ); + await generatePages(packagesPath, docsPath, pagesPath, componentsPath); expect(fs.existsSync(firstDocsPage)).toEqual(true); fs.unlinkSync(path.join(docsPath, 'doc-1.md')); @@ -371,7 +323,6 @@ describe('File modification tests', () => { [path.join(packagesPath, '/*')], docsPath, pagesPath, - bundlesPath, componentsPath, ); diff --git a/packages/website/bin/run-website.js b/packages/website/bin/run-website.js new file mode 100644 index 0000000..1f476df --- /dev/null +++ b/packages/website/bin/run-website.js @@ -0,0 +1,55 @@ +const { spawnSync } = require('child_process'); +const path = require('path'); + +const handleConfig = require('./handle-config'); +const generatePages = require('./generate-pages'); + +const cwd = process.cwd(); +const nextRoot = path.resolve(__dirname, '..'); + +const spawnNextProcess = (command, websiteConfigPath, args = '') => { + const { status } = spawnSync( + `PATH=$(npm bin):$PATH; NODE_PATH=$NODE_PATH:$PWD/src next ${command} ${args}`, + [], + { + stdio: 'inherit', + shell: true, + env: { + ...process.env, + FORCE_EXTRACT_REACT_TYPES: true, + ...(websiteConfigPath + ? { DOCS_WEBSITE_CONFIG_PATH: websiteConfigPath } + : {}), + DOCS_WEBSITE_CWD: cwd, + }, + cwd: nextRoot, + }, + ); + + if (status !== 0) { + throw new Error(`Next ${command} failed with exit code ${status}`); + } +}; + +const preNextScripts = async configPath => { + const config = handleConfig(cwd, configPath); + await generatePages(config); +}; + +const dev = async configPath => { + await preNextScripts(configPath); + spawnNextProcess('dev', configPath); +}; + +const build = async configPath => { + await preNextScripts(configPath); + spawnNextProcess('build', configPath); +}; + +const start = async configPath => { + spawnNextProcess('start', configPath, '-p 8080'); +}; + +module.exports.dev = dev; +module.exports.build = build; +module.exports.start = start; diff --git a/packages/website/bundles/.gitkeep b/packages/website/bundles/.gitkeep deleted file mode 100644 index e69de29..0000000 diff --git a/packages/website/next.config.js b/packages/website/next.config.js index 758714d..095b63a 100644 --- a/packages/website/next.config.js +++ b/packages/website/next.config.js @@ -2,30 +2,30 @@ const webpack = require('webpack'); const withMDX = require('@zeit/next-mdx')({ extension: /\.mdx?$/, }); -const path = require('path'); const withCSS = require('@zeit/next-css'); +const handleConfig = require('./bin/handle-config'); + +const configPath = process.env.DOCS_WEBSITE_CONFIG_PATH; +const cwd = process.env.DOCS_WEBSITE_CWD || process.cwd(); + +console.log(process.env); + +const { webpack: clientWebpack } = handleConfig(cwd, configPath); + module.exports = withCSS( withMDX({ pageExtensions: ['js', 'jsx', 'mdx', 'tsx', 'ts'], webpack(config) { // eslint-disable-next-line no-param-reassign config.externals = []; - // Need to apply next.js webpack to jira-frontend src modules - config.module.rules.forEach( - rule => - rule.include && - rule.include.push(path.join(__dirname, `../packages`)), - ); // Adding items to globalScope in the website config.plugins.push( new webpack.ProvidePlugin({ Props: ['pretty-proptypes', 'default'] }), ); - // Needed to make sure jira-frontend src alias are found by webpack - config.resolve.modules.push(path.join(__dirname, `../packages`)); - return config; + return clientWebpack(config); }, }), ); diff --git a/packages/website/package.json b/packages/website/package.json index 660d560..bfffaf9 100644 --- a/packages/website/package.json +++ b/packages/website/package.json @@ -10,7 +10,7 @@ "dev:webpack": "node bin/index.js dev --config=dummy-data/custom-webpack-project/docs.config.js", "build:site": "node bin/index.js build --config=dummy-data/simple-project/docs.config.js", "build": "echo no build set yet for website", - "start": "next start -p 8080" + "start": "node bin/index.js start" }, "bin": { "brisk": "bin/index.js" @@ -32,10 +32,10 @@ "@atlaskit/theme": "^6.0.0", "@atlaskit/tree": "^4.1.11", "@atlaskit/width-detector": "^0.3.1", - "@babel/preset-flow": "^7.0.0", - "@babel/preset-typescript": "^7.3.3", "@babel/plugin-proposal-class-properties": "^7.3.4", "@babel/plugin-proposal-object-rest-spread": "^7.3.4", + "@babel/preset-flow": "^7.0.0", + "@babel/preset-typescript": "^7.3.3", "@emotion/core": "^10.0.9", "@emotion/styled": "^10.0.9", "@mdx-js/loader": "^0.17.5", @@ -57,6 +57,7 @@ "lodash.capitalize": "^4.2.1", "lodash.debounce": "^4.0.8", "lodash.flatmap": "^4.5.0", + "lodash.identity": "^3.0.0", "lodash.snakecase": "^4.1.1", "next": "^7.0.2", "outdent": "^0.7.0", diff --git a/yarn.lock b/yarn.lock index a62e8d7..1e306ee 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7109,6 +7109,11 @@ lodash.get@^4.4.2: version "4.4.2" resolved "https://packages.atlassian.com/api/npm/npm-remote/lodash.get/-/lodash.get-4.4.2.tgz#2d177f652fa31e939b4438d5341499dfa3825e99" +lodash.identity@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/lodash.identity/-/lodash.identity-3.0.0.tgz#ad7bc6a4e647d79c972e1b80feef7af156267876" + integrity sha1-rXvGpOZH15yXLhuA/u968VYmeHY= + lodash.isequal@^4.5.0: version "4.5.0" resolved "https://packages.atlassian.com/api/npm/npm-remote/lodash.isequal/-/lodash.isequal-4.5.0.tgz#415c4478f2bcc30120c22ce10ed3226f7d3e18e0" @@ -9559,14 +9564,6 @@ scheduler@^0.13.3: loose-envify "^1.1.0" object-assign "^4.1.1" -scheduler@^0.13.4: - version "0.13.4" - resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.13.4.tgz#8fef05e7a3580c76c0364d2df5e550e4c9140298" - integrity sha512-cvSOlRPxOHs5dAhP9yiS/6IDmVAVxmk33f0CtTJRkmUWcb1Us+t7b1wqdzoC0REw2muC9V5f1L/w5R5uKGaepA== - dependencies: - loose-envify "^1.1.0" - object-assign "^4.1.1" - schema-utils@^0.4.4, schema-utils@^0.4.5: version "0.4.7" resolved "https://packages.atlassian.com/api/npm/npm-remote/schema-utils/-/schema-utils-0.4.7.tgz#ba74f597d2be2ea880131746ee17d0a093c68187"