Since we wanted to profit off Babel’s tranpilation, we are using Webpack and Babel to compile our Javascript (see file below).
However, today I am having the regeneratorRuntime is not defined
error.
My question is, what is the modern way to configure Babel for a Jira plugin? Would someone mind sharing your config file?
Related:
- Jira provides the polyfills,
- The original blogpost from Atlassian in 2016 still uses the polyfills, and an older version of Babel and Webpack, and the config has changed since then: Developing a JIRA add-on like it's 2016 - Atlassian Developer Blog
Here is our Webpack file:
const path = require('path');
const TerserPlugin = require('terser-webpack-plugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const fs = require('fs');
let PROD = process.env.NODE_ENV === "production";
let MINIFIED = process.env.MINIFIED === "true" ;
let GENERATE_SOURCE_MAP = !PROD;
class BundlerConfiguration {
constructor(pluginName) {
this.pluginName = pluginName;
}
getConfig() {
let config = {
mode: PROD ? 'production' : 'development',
entry: this.listJsFiles(`${__dirname}/${this.pluginName}/src/main/resources/js/entries`),
output: {
path: path.resolve(__dirname, `${this.pluginName}/target/classes/js`),
// We used to generate .js and -min.js, then I noticed the .js was sufficient for prod.
//filename: MINIFIED ? '[name]-min.js' : '[name].js'
filename: '[name].js'
},
module: {
rules: [
{
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: 'babel-loader',
options: {
presets: [[
"@babel/preset-env",
{
"targets": {
"chrome": "88",
"edge": "88",
"firefox": "85",
"ie": "11", // It's IE11 that requires 75Kb polyfills.
"safari": "13.1"
},
// "useBuiltIns": 'usage', This way it doesn't add polyfills
"debug": true
},
]]
}
}
}
]
},
resolve: {
alias: {
Include: path.resolve(
__dirname,
`${this.pluginName}/src/main/resources/js/include/`
),
Utils: path.resolve(__dirname, 'utils/src/main/resources/js/')
},
modules: [
'node_modules'
]
},
devtool: GENERATE_SOURCE_MAP ? 'source-map' : false,
// ES5 to be compatible with IE11
target: ['web', 'es5'],
stats: {
colors: true
},
optimization: {
minimize: MINIFIED,
minimizer: MINIFIED ? [
// we specify a custom UglifyJsPlugin here to get source maps in production
new TerserPlugin({
parallel: true,
terserOptions: {
compress: true,
ecma: 5,
// We don't mangle, so we can have the correct variable names in stacktraces of customer reports
mangle: false,
ie8: false,
// We don't include a source-map, since I haven't found a way to display stacktraces
// with the original file's method name and line number anyway.
sourceMap: false
},
})
] : []
},
plugins: [
// This is the copy-webpack-plugin
new CopyWebpackPlugin({
patterns: [
{
// Copy all other files, except .js, into the target directory
from: path.resolve(__dirname, `${this.pluginName}/src/main/resources`),
to: path.resolve(__dirname, `${this.pluginName}/target/classes`),
globOptions: {
ignore: [
'**/*.js',
'**/atlassian-plugin.xml', // This one is transformed/copied by Maven.
'**/Search.g4'
]
}
}
]
})
]
};
return config;
}
isDirectory(pathToFile) {
let stat = fs.statSync(pathToFile);
return stat && stat.isDirectory();
}
isJsFile(filename) {
return filename.endsWith(".js");
}
listJsFiles(pathToResource) {
const files = fs.readdirSync(pathToResource);
let results = {};
files.forEach(file => {
const pathToFileOrDir = pathToResource + '/' + file;
if (this.isJsFile(file)) {
results[path.parse(file).name] = pathToFileOrDir;
} else if (this.isDirectory(pathToFileOrDir)) {
results = Object.assign(results, this.listJsFiles(pathToFileOrDir));
}
});
return results;
}
}
module.exports = {
BundlerConfiguration: BundlerConfiguration
};