@berun/runner-webpack
Version:
Webpack runner for building React web applications
154 lines (144 loc) • 4.3 kB
text/typescript
import Berun from '@berun/berun'
// FIX-DEPENDENCIES
require.resolve('babel-loader')
require.resolve('@svgr/webpack')
require.resolve('url-loader')
require.resolve('file-loader')
/**
* Disable require.ensure as it's not a standard language feature.
*/
export const ruleParser = (berun: Berun, _) => {
berun.webpack.module.rule('parser').parser({ requireEnsure: false }).end()
}
/**
* `mjs` support is still in its infancy in the ecosystem, so we don't
* support it.
* Modules who define their `browser` or `module` key as `mjs` force
* the use of this extension, so we need to tell webpack to fall back
* to auto mode (ES Module interop, allows ESM to import CommonJS).
*/
export const ruleMjs = (berun: Berun, _) => {
berun.webpack.module
.rule('mjs')
.test([/\.mjs$/])
.include.add(/node_modules/)
.end()
.type('javascript/auto')
.use('babel')
.loader(require.resolve('babel-loader'))
.options({
babelrc: false,
configFile: false,
compact: false,
presets: [
require.resolve('@berun/babel-preset-react-app/dist/dependencies')
],
cacheDirectory: true,
cacheCompression: process.env.NODE_ENV === 'production',
highlightCode: true,
sourceMaps: false
})
}
/**
* "url" loader works like "file" loader except that it embeds assets
* smaller than specified limit in bytes as data URLs to avoid requests.
* A missing `test` is equivalent to a match.
*/
export const ruleMainImage = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('image')
.test([/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/])
.exclude.add(/node_modules/)
.end()
.use('url-loader')
.loader(require.resolve('url-loader'))
.options({ limit: 10000, name: 'static/media/[name].[hash:8].[ext]' })
}
/**
* Process application JS with Babel.
* The preset includes JSX, Flow, and some ESnext features.
*/
export const ruleMainCompile = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('compile')
.test(/\.(js|jsx|ts|tsx)$/)
.include.merge([berun.options.paths.metaWorkspace])
.end()
.exclude.add(/node_modules/)
.end()
.use('babel')
.loader(require.resolve('babel-loader'))
.options({
/* placeholder */
})
}
/**
* Process vendor node_modules TS with Babel.
* The preset includes JSX, Flow, and some ESnext features.
*/
export const ruleVendorCompileTs = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('vendorcompilets')
.test(/\.(jsx|ts|tsx)$/)
.include.merge([berun.options.paths.metaWorkspace])
.end()
.use('babel')
.loader(require.resolve('babel-loader'))
.options({
/* placeholder */
})
}
/**
* "file" loader makes sure those assets get served by WebpackDevServer.
* When you `import` an asset, you get its (virtual) filename.
* In production, they would get copied to the `build` folder.
* This loader doesn't use a "test" so it will catch all modules
* that fall through the other loaders.
*/
export const ruleMainStatic = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('static')
// Exclude `js` files to keep "css" loader working as it injects
// its runtime that would otherwise be processed through "file" loader.
// Also exclude `html` and `json` extensions so they get processed
// by webpacks internal loaders.
.exclude.add(/\.(css|scss|sass|js|jsx|mjs|ts|tsx)$/)
.add(/\.ejs$/)
.add(/\.html$/)
.add(/\.json$/)
.add(/node_modules/)
.end()
.use('file')
.loader(require.resolve('file-loader'))
.options({
name: 'static/media/[name].[hash:8].[ext]'
})
}
export const ruleMainFonts = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('ttf')
.test(/^.+\.(ttf)$/)
.use('file')
.loader(require.resolve('file-loader'))
.options({
name: 'static/fonts/[name].[hash:8].[ext]'
})
}
export const ruleMainSvg = (berun: Berun, _) => {
berun.webpack.module
.rule('main')
.oneOf('svg')
.test(/\.svg$/)
.exclude.add(/node_modules/)
.end()
.use('svgr')
.loader(require.resolve('@svgr/webpack'))
.end()
.use('svgr')
.loader(require.resolve('url-loader'))
}