Skip to content

Commit

Permalink
feat(scripts): Bootstrap scripts package
Browse files Browse the repository at this point in the history
Creating the skeleton for `@spinnaker/scripts` package with `baseRollupConfig.js` copied from
`pluginsdk/pluginconfig/rollup.config.js` and adding relevant npm dependencies.
  • Loading branch information
vigneshm committed May 18, 2021
1 parent 2ae8345 commit 8ae0d1b
Show file tree
Hide file tree
Showing 5 changed files with 2,552 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
const fs = require('fs');
const path = require('path');
const MagicString = require('magic-string');

// This rollup plugin finds AngularJS templates and loads them into the $templateCache
// This is a rollup replacement for the ngtemplate-loader webpack loader
module.exports = function angularJsTemplateLoader(options = {}) {
function isSourceMapEnabled() {
return options.sourceMap !== false && options.sourcemap !== false;
}

return {
transform(originalCode, id) {
let code = originalCode;
const templateRegex = /require\(['"]([^'"]+\.html)['"]\)/g;

// look for things like require('./template.html')
if (!code.includes("require('./") || code.includes('node_modules')) {
return;
}

if (!fs.existsSync(id)) {
throw new Error('Unable to load AngularJS template; could not find source file ' + id);
}

// Find the directory the JS source file is in
const baseDir = fs.lstatSync(id).isDirectory() ? id : path.dirname(id);

let match = templateRegex.exec(code);
if (!match) {
return;
}

let magicString = new MagicString(code);

while (match) {
// i.e., './template.html'
const templatePath = match[1];
// Absolute path to the actual template.html file
const contentPath = path.resolve(baseDir, templatePath);
if (!fs.existsSync(contentPath)) {
throw new Error('Unable to load AngularJS template; could not find template file ' + contentPath);
}

const startIdx = match.index;
const endIdx = startIdx + match[0].length;

// read the contents of template.html
const content = fs.readFileSync(contentPath, { encoding: 'UTF8' }).replace(/`/g, '\\`');

// Replace: templateUrl: require('./template.html')
// With: templateUrl: './template.html'
magicString.overwrite(startIdx, endIdx, `'${templatePath}'`);

// Append a run block that adds the HTML content into the $templateCache (used by angularjs when loading templates)
magicString.append(`
/*********************************************************************
* angularjs-template-loader rollup plugin -- ${templatePath} start *
********************************************************************/
window.angular.module('ng').run(['$templateCache', function(templateCache) {
templateCache.put('${templatePath}',
\`${content}\`)
}]);
/*********************************************************************
* angularjs-template-loader rollup plugin -- ${templatePath} end *
********************************************************************/
`);
// look for another match
match = templateRegex.exec(code);
}

if (isSourceMapEnabled()) {
return { code: magicString.toString(), map: magicString.generateMap({ hires: true }) };
} else {
return { code: magicString.toString() };
}
},
};
};
117 changes: 117 additions & 0 deletions packages/scripts/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
#!/usr/bin/env node

const chalk = require('chalk');
const fs = require('fs');
const loadConfigFile = require('rollup/dist/loadConfigFile');
const ora = require('ora');
const path = require('path');
const process = require('process');
const rollup = require('rollup');

const getRollupConfigPath = (file) => {
if (file && !fs.existsSync(path.resolve(path.join('.', file)))) {
// If the user explicitly provides a rollup config file and if it is not available, then throw an error and exit.
console.error(`Could not find ${path.join('.', file)}`);
process.exit(1);
}
// If user does't provide a rollup config file, then search for `rollup.config.js` in the project directory. If it is
// not found, then use `basePluginRollupConfig.js` which contains pretty reasonable defaults.
const projectRollupConfigFilePath = path.resolve(path.join('.', file || 'rollup.config.js'));
return fs.existsSync(projectRollupConfigFilePath)
? projectRollupConfigFilePath
: path.resolve(path.join(__dirname), 'basePluginRollupConfig.js');
};

const OUTPUT_DIR_REGEX = /\/?(\w+)$/;

const getOutputDir = (output) => {
const outputDirMatch = OUTPUT_DIR_REGEX.exec(output);
return outputDirMatch.length > 1 ? outputDirMatch[1] : output;
};

const startHandler = async ({ file }) => {
process.env.ROLLUP_WATCH = true;

const { options, warnings } = await loadConfigFile(getRollupConfigPath(file));
// A map of `input-output` bundle key to a spinner object. This is used to quickly access a spinner object when
// succeeding/failing that object on receiving a `BUNDLE_END`/`ERROR` event.
const spinners = {};
// Kick-starting rollup's bundling process in watch mode.
const watcher = rollup.watch(options);

warnings.flush();
watcher.on('event', (event) => {
// Rollup will be emitting lifecycle events for the bundling process such as start, end and error. These events are
// used to control a spinner in the terminal for each `input-output` bundle.
switch (event.code) {
case 'BUNDLE_START':
console.log('');
event.output.forEach((output) => {
const outputDir = getOutputDir(output);
const spinner = ora({
text: chalk.blue.bold(`${event.input} -> ${outputDir}`),
});
spinners[`${event.input}-${output}`] = spinner;

spinner.start();
});
break;
case 'BUNDLE_END':
event.output.forEach((output) => {
const spinner = spinners[`${event.input}-${output}`];
if (spinner) {
const outputDir = getOutputDir(output);
spinner.succeed(chalk.green.bold(`${event.input} -> ${outputDir}`));
delete spinners[`${event.input}-${output}`];
}
});
break;
case 'ERROR':
Object.entries(spinners).forEach(([key, spinner]) => {
spinner.fail(event.error);
delete spinners[key];
});
break;
}
});

watcher.close();
};

const printBundleStart = (option) => {
let message = option.output.map((output) => `${option.input} -> ${output.dir}...`).join('\n');
console.log(chalk.blue.bold(message));
};
const printBundleComplete = (option, completedTimeInMS) => {
const outputFolder = chalk.green.bold(option.output.map((output) => output.dir).join(', '));
const completedTimeInS = chalk.green.bold(`${completedTimeInMS / 1000}s`);
console.log(chalk.green(`created ${outputFolder} in ${completedTimeInS}`));
};

const buildHandler = async ({ file }) => {
const { options, warnings } = await loadConfigFile(getRollupConfigPath(file));
warnings.flush();

for (const o of options) {
const start = Date.now();
console.log('');
printBundleStart(o);

const bundle = await rollup.rollup(o);
await Promise.all(o.output.map(bundle.write));

printBundleComplete(o, Date.now() - start);
}
};

const optionsConfigurer = (yargs) =>
yargs.option('file', {
alias: '-f',
});

require('yargs')
.scriptName('spinnaker-scripts')
.command('start', 'Builds your package in watch mode', optionsConfigurer, startHandler)
.command('build', 'Builds your package', optionsConfigurer, buildHandler)
.help()
.demandCommand().argv;
34 changes: 34 additions & 0 deletions packages/scripts/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"name": "@spinnaker/scripts",
"version": "0.0.1",
"description": "",
"main": "index.js",
"bin": {
"spinnaker-scripts": "./index.js"
},
"scripts": {},
"keywords": [],
"author": "",
"license": "ISC",
"dependencies": {
"@rollup/plugin-commonjs": "^17.0.0",
"@rollup/plugin-json": "4.1.0",
"@rollup/plugin-node-resolve": "^11.0.1",
"@rollup/plugin-replace": "2.4.2",
"@rollup/plugin-typescript": "^8.1.0",
"@rollup/plugin-url": "^6.0.0",
"@spinnaker/eslint-plugin": "^1.0.13",
"autoprefixer": "^7.1.2",
"chalk": "^4.1.1",
"ora": "^5.4.0",
"postcss-nested": "^4.2.1",
"rollup": "^2.35.1",
"rollup-plugin-external-globals": "0.6.1",
"rollup-plugin-less": "1.1.3",
"rollup-plugin-postcss": "3.1.8",
"rollup-plugin-terser": "7.0.2",
"rollup-plugin-visualizer": "5.4.1",
"yargs": "^17.0.1"
},
"devDependencies": {}
}
Loading

0 comments on commit 8ae0d1b

Please sign in to comment.