Skip to content
This repository has been archived by the owner on Jan 24, 2025. It is now read-only.

Commit

Permalink
chore(docz-core): a lot of bundler improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
pedronauck committed Dec 28, 2018
1 parent c935af5 commit 0284f52
Show file tree
Hide file tree
Showing 17 changed files with 703 additions and 621 deletions.
3 changes: 2 additions & 1 deletion core/docz-core/librc.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,9 @@ module.exports = {
'react-dev-utils/formatWebpackMessages',
'react-dev-utils/getCacheIdentifier',
'react-dev-utils/ignoredFiles',
'react-dev-utils/ModuleNotFoundPlugin',
'react-dev-utils/typescriptFormatter',
'react-dev-utils/WatchMissingNodeModulesPlugin',
'react-dev-utils/WebpackDevServerUtils',
'react-dom/server',
]),
}
21 changes: 17 additions & 4 deletions core/docz-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,15 @@
"@babel/runtime": "^7.2.0",
"@mdx-js/loader": "^0.16.6",
"@sindresorhus/slugify": "^0.6.0",
"@svgr/webpack": "^4.1.0",
"babel-loader": "^8.0.2",
"babel-plugin-export-metadata": "^0.13.4",
"babel-plugin-named-asset-import": "^0.3.0",
"babel-preset-react-app": "^7.0.0",
"babylon": "^6.18.0",
"cache-loader": "^2.0.0",
"chalk": "^2.4.1",
"chokidar": "^2.0.4",
"common-tags": "^1.8.0",
"cpy": "^7.0.1",
"deepmerge": "^3.0.0",
"detect-port": "^1.3.0",
"docz-utils": "^0.13.5",
Expand All @@ -53,7 +54,6 @@
"lodash": "^4.17.11",
"mini-html-webpack-plugin": "^0.2.3",
"p-reduce": "^1.0.0",
"progress-estimator": "^0.2.2",
"react-dev-utils": "^7.0.0",
"react-docgen": "^2.21.0",
"react-docgen-actual-name-handler": "0.13.5",
Expand All @@ -69,7 +69,7 @@
"resolve": "^1.9.0",
"signale": "^1.3.0",
"source-map-loader": "^0.2.4",
"terser-webpack-plugin": "^1.2.0",
"terser-webpack-plugin": "^1.2.1",
"thread-loader": "^2.1.1",
"titleize": "^1.0.1",
"url-loader": "^1.1.2",
Expand All @@ -82,5 +82,18 @@
"webpackbar": "^3.1.4",
"ws": "^6.1.2",
"yargs": "^12.0.5"
},
"devDependencies": {
"@types/chokidar": "^1.7.5",
"@types/express": "^4.16.0",
"@types/html-minifier": "^3.5.2",
"@types/p-reduce": "^1.0.0",
"@types/resolve": "^0.0.8",
"@types/webpack": "^4.4.22",
"@types/webpack-chain": "^5.0.0",
"@types/webpack-dev-server": "^3.1.1",
"@types/ws": "^6.0.1",
"@types/yargs": "^12.0.4",
"cpy": "^7.0.1"
}
}
50 changes: 27 additions & 23 deletions core/docz-core/src/bundler/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,12 @@ import envDotProp from 'env-dot-prop'
import * as loaders from './loaders'
import * as plugins from './plugins'
import * as paths from '../config/paths'
import { BabelRC } from '../config/babel'
import { minifier } from './minifier'
import { ServerHooks } from '../lib/Bundler'
import { ServerHooks as Hooks } from '../lib/Bundler'
import { Config as Args, Env } from '../config/argv'
import { getBabelConfig } from '../config/babel'

export const createConfig = (args: Args, env: Env) => async (
babelrc: BabelRC,
hooks: ServerHooks
): Promise<Configuration> => {
export const createConfig = (args: Args, env: Env) => async (hooks: Hooks) => {
const { debug } = args

const config = new Config()
Expand Down Expand Up @@ -64,6 +61,9 @@ export const createConfig = (args: Args, env: Env) => async (
.publicPath(publicPath)
.when(isProd, outputProd, outputDev)
.crossOriginLoading('anonymous')
.devtoolModuleFilenameTemplate((info: any) =>
path.resolve(info.resourcePath).replace(/\\/g, '/')
)

/**
* entries
Expand All @@ -90,21 +90,14 @@ export const createConfig = (args: Args, env: Env) => async (
.add('.mdx')
.end()

if (args.typescript) {
config.resolve.extensions
.prepend('.ts')
.prepend('.tsx')
.end()
}

config.resolve.alias.set('~db', paths.db)
config.resolve.alias.set('~imports', paths.importsJs)
config.resolve.alias.set('react-native$', 'react-native-web')

const inYarnWorkspaces = __dirname.includes('/docz/core/docz-core')
const doczDependenciesDir = inYarnWorkspaces
? path.join(__dirname, '../../../../node_modules')
: path.join(__dirname, '../../../')
: paths.ownNodeModules

config.resolve.modules
.add('node_modules')
Expand All @@ -129,18 +122,17 @@ export const createConfig = (args: Args, env: Env) => async (
* loaders
*/

config.when(args.sourcemaps, cfg => loaders.sourceMaps(cfg))
loaders.js(config, args, babelrc)
loaders.mdx(config, args, babelrc)
const jsBabelRc = await getBabelConfig(args, env)
const tsBabelRc = await getBabelConfig(args, env, true)

config.when(args.sourcemaps, cfg => loaders.sourceMaps(cfg, args))
loaders.js(config, args, jsBabelRc)
loaders.mdx(config, args, jsBabelRc)
loaders.images(config)
loaders.svg(config)
loaders.media(config)
loaders.fonts(config)

/**
* plugins
*/

await plugins.html(config, args, env)
plugins.assets(config, args, env)
plugins.ignore(config)
Expand All @@ -150,16 +142,28 @@ export const createConfig = (args: Args, env: Env) => async (
config.when(debug, cfg => plugins.analyzer(cfg))
config.when(!isProd, cfg => plugins.watchNodeModulesPlugin(cfg))
config.when(!debug && !isProd, cfg => {
plugins.webpackBar(cfg)
plugins.webpackBar(cfg, args)
plugins.friendlyErrors(cfg, args)
})

/**
* typescript setup
*/

config.when(args.typescript, cfg => {
cfg.resolve.extensions
.prepend('.ts')
.prepend('.tsx')
.end()

loaders.ts(cfg, args, tsBabelRc)
})

/**
* optimization
*/

config.optimization
.runtimeChunk(true)
.nodeEnv(env)
.namedModules(true)
.minimize(isProd)
Expand Down
70 changes: 48 additions & 22 deletions core/docz-core/src/bundler/loaders.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,61 +9,87 @@ import * as paths from '../config/paths'
import { Config as Args } from '../config/argv'
import { BabelRC } from '../config/babel'

const outsideNodeModules = (filepath: string) => !/node_modules/.test(filepath)
const excludeNodeModules = (filepath: string) => /node_modules/.test(filepath)

export const sourceMaps = (config: Config) => {
export const sourceMaps = (config: Config, args: Args) => {
const srcPath = path.resolve(paths.root, args.src)

config.module
.rule('sourcemaps')
.test(/\.(js|mjs|jsx|ts|tsx|md|mdx)$/)
.include.add(outsideNodeModules)
.include.add(srcPath)
.add(paths.app)
.end()
.use('sourcemaps')
.loader(require.resolve('source-map-loader'))
.end()
.enforce('pre')
}

const addScriptLoaders = (rule: Config.Rule, babelrc: BabelRC, args: Args) =>
rule
.when(!args.debug, rule =>
rule
.use('cache-loader')
.loader(require.resolve('cache-loader'))
.options({
cacheDirectory: paths.cache,
})
)
.use('thread-loader')
.loader(require.resolve('thread-loader'))
.options({
workers: require('os').cpus().length - 1,
})
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelrc)
.end()

export const js = (config: Config, args: Args, babelrc: BabelRC) => {
const srcPath = path.resolve(paths.root, args.src)

config.module
const rule = config.module
.rule('js')
.test(/\.(js|mjs|jsx|ts|tsx)$/)
.test(/\.(js|mjs|jsx)$/)
.include.add(srcPath)
.add(paths.docz)
.add(paths.root)
.add(paths.app)
.end()
.exclude.add(excludeNodeModules)
.end()
.use('thread-loader')
.loader(require.resolve('thread-loader'))

addScriptLoaders(rule, babelrc, args)
}

export const ts = (config: Config, args: Args, babelrc: BabelRC) => {
const srcPath = path.resolve(paths.root, args.src)
const rule = config.module
.rule('ts')
.test(/\.(ts|tsx?)$/)
.include.add(srcPath)
.add(paths.root)
.add(paths.app)
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelrc)
.exclude.add(excludeNodeModules)
.end()

addScriptLoaders(rule, babelrc, args)
}

export const mdx = (config: Config, args: Args, babelrc: BabelRC) => {
const { mdPlugins, hastPlugins } = args
const srcPath = path.resolve(paths.root, args.src)

config.module
const rule = config.module
.rule('mdx')
.test(/\.(md|markdown|mdx)$/)
.include.add(srcPath)
.add(paths.root)
.add(paths.docz)
.end()
.exclude.add(excludeNodeModules)
.end()
.use('thread-loader')
.loader(require.resolve('thread-loader'))
.end()
.use('babel-loader')
.loader(require.resolve('babel-loader'))
.options(babelrc)
.end()

addScriptLoaders(rule, babelrc, args)
.use('mdx-loader')
.loader(require.resolve('@mdx-js/loader'))
.options({
Expand Down
16 changes: 12 additions & 4 deletions core/docz-core/src/bundler/plugins.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { minify } from 'html-minifier'
import miniHtmlWebpack from 'mini-html-webpack-plugin'
import manifestPlugin from 'webpack-manifest-plugin'
import watchMissingNodeModules from 'react-dev-utils/WatchMissingNodeModulesPlugin'
import moduleNotFoundPlugin from 'react-dev-utils/ModuleNotFoundPlugin'
import { BundleAnalyzerPlugin } from 'webpack-bundle-analyzer'

import * as paths from '../config/paths'
Expand Down Expand Up @@ -79,7 +80,11 @@ export const ignore = (config: Config) => {
export const hot = (config: Config) => {
config
.plugin('hot-module-replacement')
.use(HotModuleReplacementPlugin as any, [])
.use(HotModuleReplacementPlugin as any, [
{
multiStep: true,
},
])
}

export const html = async (config: Config, args: Args, env: Env) => {
Expand Down Expand Up @@ -114,12 +119,11 @@ export const html = async (config: Config, args: Args, env: Env) => {
])
}

export const webpackBar = (config: Config) => {
export const webpackBar = (config: Config, args: Args) => {
config.plugin('webpackbar').use(webpackBarPlugin, [
{
name: 'Docz',
color: '#41b883',
compiledIn: false,
name: 'Client',
},
])
}
Expand All @@ -129,3 +133,7 @@ export const watchNodeModulesPlugin = (config: Config) => {
.plugin('watch-missing-node-modules')
.use(watchMissingNodeModules, [paths.appNodeModules])
}

export const notFoundPlugin = (config: Config) => {
config.plugin('not-found-plugin').use(moduleNotFoundPlugin, [paths.root])
}
53 changes: 25 additions & 28 deletions core/docz-core/src/bundler/server.ts
Original file line number Diff line number Diff line change
@@ -1,37 +1,34 @@
import * as fs from 'fs'
import chalk from 'chalk'
import logger from 'signale'
import { Configuration as Config } from 'webpack'
import WebpackDevServer from 'webpack-dev-server'
import { Configuration as Config } from 'webpack'

import * as paths from '../config/paths'
import { devServerConfig } from './devserver'
import { Config as Args } from '../config/argv'
import { ServerHooks as Hooks } from '../lib/Bundler'
import * as serverUtils from 'react-dev-utils/WebpackDevServerUtils'

export const server = (args: Args) => async (config: Config, hooks: Hooks) => {
const useYarn = fs.existsSync(paths.appYarnLock)
const protocol = process.env.HTTPS === 'true' ? 'https' : 'http'
const appName = require(paths.appPackageJson).name
const urls = serverUtils.prepareUrls(protocol, args.host, args.port)
const serverConfig: any = devServerConfig(hooks, args)

const compiler = serverUtils.createCompiler(
require('webpack'),
config,
appName,
urls,
useYarn
)
const createCompiler = (config: Config) =>
new Promise<any>(resolve => {
try {
resolve(require('webpack')(config))
} catch (err) {
logger.fatal(chalk.red('Failed to compile.'))
logger.fatal()
logger.fatal(err.message || err)
logger.fatal()
process.exit(1)
}
})

return {
start: async () => {
const devServer = new WebpackDevServer(compiler, serverConfig)
export const server = (args: Args) => async (config: Config, hooks: Hooks) => ({
start: async () => {
const serverConfig: any = devServerConfig(hooks, args)
const compiler = await createCompiler(config)
const devServer = new WebpackDevServer(compiler, serverConfig)

return devServer.listen(args.port, args.host, err => {
if (err) return logger.fatal(err)
hooks.onServerListening<WebpackDevServer>(devServer)
})
},
}
}
return devServer.listen(args.port, args.host, err => {
if (err) return logger.fatal(err)
hooks.onServerListening<WebpackDevServer>(devServer)
})
},
})
2 changes: 1 addition & 1 deletion core/docz-core/src/commands/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { parseConfig } from '../config/docz'
import { bundler as webpack } from '../bundler'
import * as states from '../states'

export const build = async (args: Arguments) => {
export const build = async (args: Arguments<any>) => {
const env = envDotProp.get('node.env')
const config = await parseConfig(args)
const entries = new Entries(config)
Expand Down
Loading

0 comments on commit 0284f52

Please sign in to comment.