Skip to content
This repository has been archived by the owner on May 10, 2021. It is now read-only.

Commit

Permalink
Add customizeBabelOptions() and rename getBabelConfig() to getBabelOp…
Browse files Browse the repository at this point in the history
…tions()
  • Loading branch information
esamattis committed Apr 8, 2021
1 parent c183d0e commit f7a479d
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 45 deletions.
58 changes: 56 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ Ex.
```js
module.exports = createWebpackConfig({
babelPlugins: [
args => {
(args) => {
if (args.mode === "production") {
return "emotion";
}
Expand Down Expand Up @@ -149,13 +149,67 @@ creating your own `babel.config.js`, `.babelrc.js` or `.baberc` file.
`process.env.NODE_ENV` is exposed to Javascript based Babel config files
based on the Webpack `--mode` argument.

For advanced use cases you can provide `customizeBabelOptions()` function to
`createWebpackConfig()` for more fine grained dynamic customization. The
`customizeBabelOptions()` will get object object of following interface:

```ts
interface CustomizeParam {
/**
* The babel plugin and preset configuration generated by @valu/webpack-config
*/
options: BabelOptions;

/**
* Babel options read from .babelrc, babel.config.js etc.
*/
babelrcOptions: BabelOptions;

/*
* Is true when babel config was read from the filesystem
*/
hasFilesystemConfig: boolean;

/*
* Full path to the babel config file (if any)
*/
babelrc: string;

/**
* Current file beign transpiled
*/
filename: string;
}
```

If you return an object from this function it will be used as the babel
config for the given file. If falsy value is returned no changes are made.

Example

```js
module.exports = createWebpackConfig({
outputPath: __dirname + "/test-app",
entry: __dirname + "/test-app/index.ts",
customizeBabelOptions(babel) {
// Force my-extra-plugin to be present when custom .babelrc file is used
if (babel.hasFilesystemConfig) {
babel.babelrcOptions.plugins.push("my-extra-plugin");
return babel.babelrcOptions;
}

return babel.options;
},
});
```

# Full customization

The full generated Webpack configuration can be customized with the
customizer callback:

```js
module.exports = createWebpackConfig(options, config => {
module.exports = createWebpackConfig(options, (config) => {
config.entry.myExtraEntry = "./src/other.js";
});
```
Expand Down
40 changes: 40 additions & 0 deletions babel-loader.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
const customizedBabelLoader = require("babel-loader").custom(() => {
return {
config(cfg) {
const config = global.valuWebpackConfig;
if (!config || !config.babelOptions) {
throw new Error(
"bug: global.valuWebpackConfig.babelOptions not defined"
);
}

let options = config.babelOptions;
let hasFsConfig = cfg.hasFilesystemConfig();

if (typeof config.customizeBabelOptions === "function") {
const custom = config.customizeBabelOptions({
options,
babelrc: cfg.babelrc,
filename: cfg.options.filename,
babelrcOptions: {
plugins: cfg.options.plugins || [],
presets: cfg.options.presets || [],
},
hasFilesystemConfig: hasFsConfig,
});

if (custom) {
return {...cfg.options, ...custom};
}
}

if (hasFsConfig) {
return cfg.options;
}

return {...cfg.options, ...options};
},
};
});

module.exports = customizedBabelLoader;
16 changes: 14 additions & 2 deletions create-webpack-config.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,16 @@
*/
export function autoloadEntries(dir: string): {[key: string]: string};

interface HtmlPluginOptions {
export interface HtmlPluginOptions {
template: string;
}

export interface BabelOptions {
presets: any[];
plugins: any[];
[key: string]: any;
}

interface Options {
/**
* Port to listen with the dev server
Expand Down Expand Up @@ -94,7 +100,13 @@ interface Options {
/**
* Manual customization of babel config without opt-in to a babelrc file
*/
customizeBabel?: (config: {plugings: any[]; presets: any[]}) => any;
customizeBabelOptions?: (babel: {
defaultOptions: BabelOptions;
babelrcOptions: BabelOptions;
babelrc: string;
filename: string;
hasFilesystemConfig: boolean;
}) => any;

/**
* Toggle manifest creation. Defaults to true
Expand Down
85 changes: 44 additions & 41 deletions create-webpack-config.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// @ts-check
const webpack = require("webpack");
const fs = require("fs");
const {join} = require("path");
const {join, resolve} = require("path");
const {execSync} = require("child_process");
const gitRev = execSync("git rev-parse HEAD").toString();
const gitDate = new Date(
Expand Down Expand Up @@ -34,14 +34,6 @@ function autoloadEntries(dir) {
}, {});
}

/**
* @param {string} dir
*/
function hasBabelrc(dir) {
const rcFiles = ["babel.config.js", ".babelrc", ".babelrc.js"];
return fs.readdirSync(dir).some((file) => rcFiles.includes(file));
}

/**
* @param {string} dir
*/
Expand Down Expand Up @@ -104,7 +96,7 @@ function getBabelLoaderConfig(options = {}) {
extensions: EXTENSIONS,
},
use: {
loader: "babel-loader",
loader: resolve(__dirname, "babel-loader.js"),
},
exclude(modulePath) {
const nodeModuleToCompile = pathMatchers.some((includeModule) =>
Expand Down Expand Up @@ -165,7 +157,7 @@ function getCssLoaderConfig(options = {}) {
*
* @param {{envConfig?: any} | undefined} options
*/
function getBabelConfig(options) {
function getBabelOptions(options) {
return {
presets: [
"@babel/preset-typescript",
Expand Down Expand Up @@ -268,6 +260,12 @@ function extractCommons() {
}

function createWebpackConfig(options = {}, customize) {
if (options.emotion) {
throw new Error(
"Emotion option is gone. Use babelPlugins option to enable it manually"
);
}

return (_, args) => {
const isProduction = args.mode === "production";
// For some reason --mode option does not set NODE_ENV for .babelrc.js
Expand Down Expand Up @@ -302,44 +300,43 @@ function createWebpackConfig(options = {}, customize) {
config.entry = options.entry;
}

const babelLoader = getBabelLoaderConfig({
compileNodeModules: options.compileNodeModules,
});

if (options.webpackPlugins) {
config.plugins.push(...options.webpackPlugins);
}

config.module.rules.push(babelLoader);

if (!hasBabelrc(process.cwd())) {
const babelConfig = getBabelConfig({
envConfig: options.babelEnv,
});

if (args.hot) {
babelConfig.plugins.push("react-hot-loader/babel");
}
config.module.rules.push(
getBabelLoaderConfig({
compileNodeModules: options.compileNodeModules,
})
);

if (options.emotion) {
throw new Error(
"Emotion option is gone. Use babelPlugins option to enable it manually"
);
}
const babelOptions = getBabelOptions({
envConfig: options.babelEnv,
});

if (options.babelPlugins) {
options.babelPlugins.forEach((plugin) => {
if (typeof plugin === "function") {
babelConfig.plugins.push(plugin(args));
} else {
babelConfig.plugins.push(plugin);
}
});
}
if (args.hot) {
babelOptions.plugins.push("react-hot-loader/babel");
}

babelLoader.use.options = babelConfig;
if (options.babelPlugins) {
options.babelPlugins.forEach((plugin) => {
if (typeof plugin === "function") {
babelOptions.plugins.push(plugin(args));
} else {
babelOptions.plugins.push(plugin);
}
});
}

// Global read by ./babel-loader.js
Object.assign(global, {
valuWebpackConfig: {
customizeBabelOptions: options.customizeBabelOptions,
args: args,
babelOptions,
},
});

if (options.extractCommons && options.entry) {
Object.assign(config.optimization, extractCommons());
}
Expand Down Expand Up @@ -443,6 +440,12 @@ function createWebpackConfig(options = {}, customize) {

module.exports = {
createWebpackConfig,
getBabelConfig,
getBabelConfig: (options) => {
console.warn(
"[@valu/webpack-config Deprecated] getBabelConfig() has been renamed to getBabelOptions()"
);
return getBabelOptions(options);
},
getBabelOptions,
autoloadEntries,
};
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
"webpack"
],
"files": [
"babel-loader.js",
"create-webpack-config.js",
"create-webpack-config.d.ts"
],
Expand Down

0 comments on commit f7a479d

Please sign in to comment.