I currently use neutrinojs to build my react code, but it is no longer maintained. I want to switch the building of my project to webpack. Is there any automated tool to do this?
This is how my neutrino config file looks like,
const airbnb = require("@neutrinojs/airbnb");
const react = require("@neutrinojs/react");
const jest = require("@neutrinojs/jest");
const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin;
const MomentLocalesPlugin = require('moment-locales-webpack-plugin');
const merge = require("deepmerge");
const AssetsPlugin = require('assets-webpack-plugin');
const { extname, join, basename } = require("path");
const { readdirSync } = require("fs");
let prodMains = {};
// Adds user controls to entry points
const components = join(__dirname, "src", "my-output");
readdirSync(components).forEach((component) => {
// eslint-disable-next-line no-param-reassign
prodMains[basename(component, extname(component))] = {
entry: join(components, component),
};
});
// Adds custom fields to entry points
const customFields = join(__dirname, "src", "my-fields-output");
readdirSync(customFields).forEach((component) => {
// eslint-disable-next-line no-param-reassign
prodMains[basename(component, extname(component))] = {
entry: join(customFields, component),
};
});
let devMains = {
index: {
entry: __dirname + "\\src\\index.jsx",
},
};
/* END of Entry point conf */
const styleConf = {
// Override the default file extension of `.css` if needed
test: /\.(css|sass|scss)$/,
modules: true,
modulesTest: /\.module\.(css|sass|scss)$/,
extract: {
enabled: false,
},
loaders: [
plugin
{
loader: "postcss-loader",
options: {
plugins: [require("autoprefixer")],
},
},
{
loader: "sass-loader",
useId: "sass",
},
],
};
module.exports = {
use: [
airbnb({
exclude: [__dirname + "\\src\\shared\\expression-parser\\"],
eslint: {
cache: false,
baseConfig: {
env: {
es6: true,
browser: true,
node: true,
},
rules: {
"linebreak-style": 0,
"no-multiple-empty-lines": 0,
"no-trailing-spaces": 0,
"max-len": 0,
"jsx-a11y/label-has-associated-control": "off",
"no-param-reassign": "off",
"object-curly-newline": 0,
},
},
},
}),
(neutrino) => {
console.log("Environment: ", process.env.NODE_ENV);
neutrino.config.when(
process.env.NODE_ENV === "production",
() => { neutrino.options.mains = prodMains; },
() => { neutrino.options.mains = devMains; }
);
const babelConfig = {
presets: [
[
"@babel/preset-react", {
useBuiltIns: false, // Will use the native built-in instead of trying to polyfill behavior for any plugins that require one.
development: process.env.NODE_ENV === "development",
},
],
],
plugins: ["macros"],
};
neutrino.config.when(
process.env.NODE_ENV === "production",
() => {
neutrino.use(
react({
html: null,
style: styleConf,
targets: false,
devtool: { production: process.argv.includes("--dev") ? "cheap-module-eval-source-map" : undefined },
babel: babelConfig,
})
);
},
() => {
const devServerConfig = {
port: 9000,
proxy: [],
};
if (process.argv.includes("--iis")) {
devServerConfig.proxy.push({
context: ["/images"],
target: `http://localhost:5000`, //IIS Server
logLevel: "debug",
});
} else {
devServerConfig.proxy.push({
context: ["/images2", "/images"],
target: "http://localhost:5675", //Mock Server
});
}
neutrino.use(
react({
hot: true,
image: true,
style: true,
font: true,
html: { title: "My App" },
style: styleConf,
targets: false,
babel: babelConfig,
devServer: devServerConfig,
})
);
}
);
neutrino.config.module
.rule("compile")
.use("babel")
.tap((options) =>
merge(options, {
sourceType: "unambiguous",
cacheDirectory: false,
})
);
// build moment with 'en' (default) and 'en-gb' locales.
neutrino.config.plugin('moment-locales')
.use(MomentLocalesPlugin, [{
localesToKeep: ['en-gb'],
}]);
neutrino.config.when(process.env.NODE_ENV === "production", (config) => {
config.plugin('assets')
.use(AssetsPlugin, [{
prettyPrint: true,
path: join(__dirname, "../mydir"),
useCompilerPath: false,
}]);
config.output
.path(
join(__dirname, "../mydir/mycon")
)
.filename((chunkData) => {
const { chunk: { entryModule: { _identifier: outputPath } } } = chunkData;
return (outputPath.includes('my-output')) ? "[name]-[hash].js" : "[name].js"} )
.chunkFilename("[name]-[hash].js")
.libraryTarget("umd");
config.performance
.hints(false)
.maxEntrypointSize(1000000) //bytes ~ 1mb
.maxAssetSize(1000000);
config.optimization
.minimize(true)
.runtimeChunk(false)
.splitChunks({
cacheGroups: {
commons: {
test: /[\\/]node_modules[\\/]/,
name: "commons-vendors",
chunks: "all",
},
},
});
if (process.argv.includes("--analyze")) {
//Bundle analyzer
config.plugin('analyzer')
.use(BundleAnalyzerPlugin, [{
reportFilename: '_report.html',
analyzerMode: 'static', // server | static | json
openAnalyzer: true,
generateStatsFile: false,
logLevel: 'info'
}]);
}
config.externals({
react: "React",
"react-dom": "ReactDOM",
"pubsub-js": "PubSub",
"sheetjs-style": "XLSX",
});
});
},
jest({
setupFilesAfterEnv: ["<rootDir>src/setupTests.js"],
testRegex: "src/.*(__tests__|_spec|\\.test|\\.spec)\\.(mjs|jsx|js)$",
moduleFileExtensions: ["tsx", "js"],
verbose: false,
timers: "fake",
collectCoverage: false,
collectCoverageFrom: [
"./src/api/**/*.{js,jsx}",
"./src/app/hooks/**/*.{js,jsx}",
"./src/utils/**/*.{js,jsx}",
],
coveragePathIgnorePatterns: [
"src/app/.*/provider.jsx",
"src/app/components/toast-message/index.jsx",
"src/app/features/translation/index.jsx",
"src/app/features/translation/locales/",
"src/app/features/providers.jsx",
"src/shared/.*/index.js",
],
coverageThreshold: {
global: {
// global thresholds
branches: 80,
functions: 80,
lines: 80,
statements: 80,
}
},
moduleNameMapper: {
"\\.(css|scss)$": "identity-obj-proxy",
},
reporters: ["default", "jest-junit"],
})
]
};