Project

General

Profile

Download (9.3 KB) Statistics
| Branch: | Tag: | Revision:
caa81e6f Ohad Levy
/* eslint-disable no-var*/
e2a57bfe Tomer Brisker
'use strict';

var path = require('path');
var webpack = require('webpack');
89c61045 MariaAga
const dotenv = require('dotenv');
dotenv.config();
074471af Amir Fefer
var ForemanVendorPlugin = require('@theforeman/vendor')
.WebpackForemanVendorPlugin;
var StatsWriterPlugin = require('webpack-stats-plugin').StatsWriterPlugin;
123df74a Ron Lavi
var vendorEntry = require('./webpack.vendor');
bc486dd6 Tomas Strachota
var fs = require('fs');
89c61045 MariaAga
const { ModuleFederationPlugin } = require('webpack').container;
var pluginUtils = require('../script/plugin_webpack_directories');
4550a0c1 MariaAga
var { generateExportsFile }= require('../webpack/assets/javascripts/exportAll');
6cafc684 Evgeni Golov
var CompressionPlugin = require('compression-webpack-plugin');
bc486dd6 Tomas Strachota
89c61045 MariaAga
class AddRuntimeRequirement {
// to avoid "webpackRequire.l is not a function" error
// enables use of webpack require inside promise new promise
apply(compiler) {
compiler.hooks.compilation.tap('AddRuntimeRequirement', compilation => {
const { RuntimeGlobals } = compiler.webpack;
compilation.hooks.additionalModuleRuntimeRequirements.tap(
'AddRuntimeRequirement',
(module, set) => {
set.add(RuntimeGlobals.loadScript);
}
);
});
}
}
5f911c19 Tomas Strachota
123df74a Ron Lavi
const supportedLocales = () => {
const localeDir = path.join(__dirname, '..', 'locale');

// Find all files in ./locale/*
const localesFiles = fs.readdirSync(localeDir);

// Return only folders
return localesFiles.filter(f =>
fs.statSync(path.join(localeDir, f)).isDirectory()
);
};

const supportedLanguages = () => {
// Extract extract languages from the language tags (strip off dialects)
return [...new Set(supportedLocales().map(d => d.split('_')[0]))];
};

89c61045 MariaAga
const supportedLanguagesRE = new RegExp(
`/(${supportedLanguages().join('|')})$`
);
5f911c19 Tomas Strachota
89c61045 MariaAga
const commonConfig = function() {
b0ee9fd6 Eric D. Helms
var production =
process.env.RAILS_ENV === 'production' ||
process.env.NODE_ENV === 'production';
89c61045 MariaAga
const mode = production ? 'production' : 'development';
const config = {};
if (production) {
config.devtool = 'source-map';
config.optimization = {
moduleIds: 'named',
splitChunks: false,
};
b0ee9fd6 Eric D. Helms
} else {
89c61045 MariaAga
config.devtool = 'inline-source-map';
config.optimization = {
splitChunks: false,
};
b0ee9fd6 Eric D. Helms
}
89c61045 MariaAga
return {
...config,
mode,
b0ee9fd6 Eric D. Helms
resolve: {
89c61045 MariaAga
fallback: {
path: require.resolve('path-browserify'),
os: require.resolve('os-browserify'),
},
alias: {
foremanReact: path.join(
__dirname,
'../webpack/assets/javascripts/react_app'
),
},
},
resolveLoader: {
modules: [path.resolve(__dirname, '..', 'node_modules')],
b0ee9fd6 Eric D. Helms
},
module: {
rules: [
{
test: /\.js$/,
b674b25e Gilad Lekner
/* Include novnc, unidiff in webpack, transpiling is needed for phantomjs (which does not support ES6) to run tests
unidiff can be removed once https://github.com/mvoss9000/unidiff/pull/1 is merged */
exclude: /node_modules(?!\/(@novnc|unidiff))/,
b0ee9fd6 Eric D. Helms
loader: 'babel-loader',
1944da62 Tomer Brisker
options: {
presets: [require.resolve('@theforeman/builder/babel')],
},
b0ee9fd6 Eric D. Helms
},
{
8a80ef08 Fellipe Henrique
test: /\.(png|gif|svg)$/,
89c61045 MariaAga
type: 'asset',
parser: {
dataUrlCondition: {
maxSize: 32767,
},
},
0aebf308 Ondrej Prazak
},
{
test: /\.(graphql|gql)$/,
exclude: /node_modules/,
loader: 'graphql-tag/loader',
074471af Amir Fefer
},
],
b0ee9fd6 Eric D. Helms
},
plugins: [
074471af Amir Fefer
new ForemanVendorPlugin({
89c61045 MariaAga
mode,
8d46433b Amir Fefer
}),
b0ee9fd6 Eric D. Helms
new webpack.DefinePlugin({
'process.env': {
89c61045 MariaAga
NODE_ENV: JSON.stringify(mode),
10959277 Gilad Lekner
NOTIFICATIONS_POLLING: process.env.NOTIFICATIONS_POLLING,
074471af Amir Fefer
REDUX_LOGGER: process.env.REDUX_LOGGER,
},
b0ee9fd6 Eric D. Helms
}),
123df74a Ron Lavi
// limit locales from intl only to supported ones
new webpack.ContextReplacementPlugin(
/intl\/locale-data\/jsonp/,
supportedLanguagesRE
),
// limit locales from react-intl only to supported ones
new webpack.ContextReplacementPlugin(
/react-intl\/locale-data/,
supportedLanguagesRE
),
89c61045 MariaAga
new AddRuntimeRequirement(),
6cafc684 Evgeni Golov
new CompressionPlugin(),
123df74a Ron Lavi
],
89c61045 MariaAga
stats: process.env.WEBPACK_STATS || 'normal',
e2a57bfe Tomer Brisker
};
89c61045 MariaAga
};
e2a57bfe Tomer Brisker
89c61045 MariaAga
const coreConfig = function() {
var config = commonConfig();
var manifestFilename = 'manifest.json';
var bundleEntry = path.join(
__dirname,
'..',
'webpack/assets/javascripts/bundle.js'
123df74a Ron Lavi
);
89c61045 MariaAga
config.context = path.resolve(__dirname, '..');
config.entry = {
43a7a4f2 Evgeni Golov
bundle: { import: bundleEntry, dependOn: ['vendor', 'reactExports'] },
89c61045 MariaAga
vendor: vendorEntry,
4550a0c1 MariaAga
reactExports: path.join(
__dirname,
'..',
'webpack/assets/javascripts/all_react_app_exports.js'
),
89c61045 MariaAga
};
config.output = {
path: path.join(__dirname, '..', 'public', 'webpack'),
publicPath: '/webpack/',
4550a0c1 MariaAga
library: {
name: ['TheForeman', '[name]'],
type: 'var',
},
89c61045 MariaAga
};
var plugins = config.plugins;
123df74a Ron Lavi
89c61045 MariaAga
plugins.push(
new ModuleFederationPlugin({
name: 'foremanReact',
})
);
plugins.push(
new StatsWriterPlugin({
filename: manifestFilename,
})
);
config.plugins = plugins;
var rules = config.module.rules;
rules.push({
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
06190391 MariaAga
attributes: { id: 'foreman_core_css' },
b0ee9fd6 Eric D. Helms
},
89c61045 MariaAga
},
'css-loader',
'sass-loader',
],
});
config.module.rules = rules;
return config;
};

const pluginConfig = function(plugin) {
const pluginRoot = plugin.root;
const pluginName = plugin.name.replace('-', '_'); // module federation doesnt like -
var config = commonConfig();
config.context = path.join(pluginRoot, 'webpack');
config.entry = {};
4550a0c1 MariaAga
function convertImportStatement(importStatement) {
const importPath = importStatement;
const importPathParts = importPath.split('/');
const newImportName = importPathParts.slice(1).join('_');
return newImportName;
}
config.externals = function({ request }, callback) {
if (/^foremanReact(\/.*)?$/.test(request)) {
const prefix = 'var TheForeman.reactExports.';
const newPath = prefix + convertImportStatement(request.substring('foremanReact'.length));
return callback(null, newPath);
}
return callback();
};
89c61045 MariaAga
var pluginEntries = {
'./index': path.resolve(pluginRoot, 'webpack', 'index'),
};
plugin.entries.filter(Boolean).forEach(entry => {
pluginEntries[`./${entry}_index`] = path.resolve(
pluginRoot,
'webpack',
`${entry}_index`
b0ee9fd6 Eric D. Helms
);
89c61045 MariaAga
});

if (config.mode == 'production') {
var outputPath = path.join(pluginRoot, 'public', 'webpack', pluginName);
b0ee9fd6 Eric D. Helms
} else {
89c61045 MariaAga
var outputPath = path.join(
__dirname,
'..',
'public',
'webpack',
pluginName
b0ee9fd6 Eric D. Helms
);
}
89c61045 MariaAga
config.output = {
path: outputPath,
publicPath: '/webpack/' + pluginName + '/',
uniqueName: pluginName,
};
var configModules = config.resolve.modules || [];
// make webpack to resolve modules from core first
configModules.unshift(path.resolve(__dirname, '..', 'node_modules'));
// add plugin's node_modules to the reslver list
configModules.push(path.resolve(pluginRoot, 'node_modules'));
84f33a33 Evgeni Golov
configModules.push('node_modules/');
89c61045 MariaAga
config.resolve.modules = configModules;

//get the list of webpack plugins
var plugins = config.plugins;
4550a0c1 MariaAga
89c61045 MariaAga
plugins.push(
new ModuleFederationPlugin({
name: pluginName,
filename: pluginName + '_remoteEntry.js',
exposes: pluginEntries,
})
);
config.plugins = plugins;
var rules = config.module.rules;
rules.push({
test: /\.(sa|sc|c)ss$/,
use: [
{
loader: 'style-loader',
options: {
injectType: 'singletonStyleTag',
06190391 MariaAga
attributes: { id: `${pluginName}_css` },
89c61045 MariaAga
},
},
'css-loader',
'sass-loader',
],
});
config.module.rules = rules;
b0ee9fd6 Eric D. Helms
return config;
074471af Amir Fefer
};
89c61045 MariaAga
module.exports = function(env, argv) {
4550a0c1 MariaAga
generateExportsFile();
89c61045 MariaAga
const { pluginName } = env;
var pluginsDirs = pluginUtils.getPluginDirs('pipe');
var pluginsInfo = {};
var pluginsConfigEnv = [];
var pluginDirKeys = Object.keys(pluginsDirs.plugins);
if (pluginName) {
pluginDirKeys = pluginDirKeys.filter(key => key.includes(pluginName));
}
pluginDirKeys.forEach(pluginDirKey => {
const parts = pluginDirKey.split(':');
const name = parts[0];
const entry = parts[1];
if (pluginsInfo[name]) {
pluginsInfo[name].entries.push(entry);
} else {
pluginsInfo[name] = {
name,
entries: [entry],
root: pluginsDirs.plugins[pluginDirKey].root,
};
}
if (!pluginDirKey.includes(':')) {
const keysWithExtras = pluginDirKeys.filter(key =>
key.includes(pluginDirKey + ':')
);
// for example: {global: true, routes: true}
const pluginExtras = keysWithExtras.map(key => ({
[key.split(':')[1]]: true,
}));
pluginsConfigEnv.push({
plugin: {
...pluginExtras,
name: pluginDirKey,
root: pluginsDirs.plugins[pluginDirKey].root,
},
});
}
});
let configs = [];
const pluginsInfoValues = Object.values(pluginsInfo);
if (pluginsInfoValues.length > 0) {
configs = pluginsInfoValues.map(plugin => pluginConfig(plugin));
}
if (pluginName) return configs;

return [coreConfig(env, argv), ...configs];
};