Files

113 lines
4.3 KiB
JavaScript

const webpackConfig = require("./webpack.typescript");
const webpack = require("webpack");
const ReactRefreshWebpackPlugin = require('@pmmmwh/react-refresh-webpack-plugin');
module.exports = (env) => {
env = env || {};
const hmr = env.hmr;
const production = env.production;
const isAnySourceMapEnabled = !!env.sourceMap || !!env.hiddenSourceMap;
const babelOptions = {
sourceMaps: isAnySourceMapEnabled ? "inline" : false,
babelrc: false,
presets: [
// https://github.com/Microsoft/TypeScript-Babel-Starter
"@babel/env",
"@babel/typescript",
"@babel/react"
],
plugins: [
...(
hmr && !production ?
[
require.resolve('react-refresh/babel')
] :
[]
),
["@babel/plugin-proposal-class-properties", { loose: true }]
]
};
const baseConfig = webpackConfig(env);
// Remove ts-loader as we'll be using Babel to transpile the TypeScript instead.
baseConfig.module.rules = baseConfig.module.rules.filter((rule) => {
const isTsLoader = rule.use && rule.use.loader === "ts-loader";
return !isTsLoader;
});
// Modify "nativescript-dev-webpack/hmr/hot-loader" to test for .tsx files
// (and also js(x) files, which it should have been doing to begin with!)
baseConfig.module.rules.some(rule => {
const isNativeScriptDevWebpackHotLoader = rule.use === "nativescript-dev-webpack/hmr/hot-loader";
if(isNativeScriptDevWebpackHotLoader){
rule.test = /\.(ts|tsx|js|jsx|css|scss|html|xml)$/;
}
return isNativeScriptDevWebpackHotLoader; // Break loop once we've found the one.
});
baseConfig.module.rules.push(
{
test: /\.[jt]s(x?)$/,
exclude: /node_modules/,
use: [
{
loader: "babel-loader",
options: babelOptions
}
],
}
);
baseConfig.resolve.extensions = [".ts", ".tsx", ".js", ".jsx", ".scss", ".css"];
baseConfig.resolve.alias["react-dom"] = "react-nativescript";
// Remove ForkTsCheckerWebpackPlugin because, now that we're using Babel, we'll leave type-checking to the IDE instead.
baseConfig.plugins = baseConfig.plugins.filter(plugin => {
const isForkTsCheckerWebpackPlugin = plugin && plugin.constructor && plugin.constructor.name === "ForkTsCheckerWebpackPlugin";
return !isForkTsCheckerWebpackPlugin;
});
// Augment NativeScript's existing DefinePlugin definitions with a few more of our own.
let existingDefinePlugin;
baseConfig.plugins = baseConfig.plugins.filter(plugin => {
const isDefinePlugin = plugin && plugin.constructor && plugin.constructor.name === "DefinePlugin";
existingDefinePlugin = plugin;
return !isDefinePlugin;
});
const newDefinitions = {
...existingDefinePlugin.definitions,
/* For various libraries in the React ecosystem. */
"__DEV__": production ? "false" : "true",
"__TEST__": "false",
/*
* Primarily for React Fast Refresh plugin, but technically the forceEnable option could be used instead.
* Worth including anyway, as there are plenty of Node libraries that use this flag.
*/
"process.env.NODE_ENV": JSON.stringify(production ? "production" : "development"),
};
baseConfig.plugins.unshift(new webpack.DefinePlugin(newDefinitions));
/**
* Set forceEnable to `true` if you want to use HMR on a production build.
*/
const forceEnable = false;
if(hmr && (!production || forceEnable)){
baseConfig.plugins.push(new ReactRefreshWebpackPlugin({
/**
* Maybe one day we'll implement an Error Overlay, but the work involved is too daunting for now.
* @see https://github.com/pmmmwh/react-refresh-webpack-plugin/issues/79#issuecomment-644324557
*/
overlay: false,
forceEnable,
}));
} else {
baseConfig.plugins = baseConfig.plugins.filter(p => !(p && p.constructor && p.constructor.name === "HotModuleReplacementPlugin"));
}
return baseConfig;
};