Skip to content

Commit

Permalink
Merge pull request #10 from homer0/next
Browse files Browse the repository at this point in the history
v1.2.0
  • Loading branch information
Leonardo Apiwan authored Jul 6, 2018
2 parents 88a9d4f + 62a78a0 commit 615c9a7
Show file tree
Hide file tree
Showing 23 changed files with 871 additions and 56 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,12 @@
"name": "projext-plugin-rollup",
"description": "Allows projext to use Rollup as a build engine.",
"homepage": "https://homer0.github.io/projext-plugin-rollup/",
"version": "1.1.0",
"version": "1.2.0",
"repository": "homer0/projext-plugin-rollup",
"author": "Leonardo Apiwan (@homer0) <me@homer0.com>",
"license": "MIT",
"dependencies": {
"projext": "^4.0.0",
"projext": "^4.1.0",
"wootils": "^1.3.2",
"jimple": "1.5.0",
"fs-extra": "6.0.1",
Expand Down
173 changes: 173 additions & 0 deletions src/plugins/copy/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
const path = require('path');
const fs = require('fs-extra');
const extend = require('extend');
const { deferred } = require('wootils/shared');
/**
* This is a Rollup plugin that copies specific files during the bundling process.
*/
class ProjextRollupCopyPlugin {
/**
* @param {ProjextRollupCopyPluginOptions} [options={}]
* The options to customize the plugin behaviour.
* @param {string} [name='projext-rollup-plugin-copy']
* The name of the plugin's instance.
*/
constructor(options, name = 'projext-rollup-plugin-copy') {
/**
* The plugin options.
* @type {ProjextRollupCopyPluginOptions}
* @access protected
* @ignore
*/
this._options = extend(
true,
{
files: [],
stats: () => {},
},
options
);
/**
* The name of the plugin's instance.
* @type {string}
*/
this.name = name;
// Validate the received options before doing anything else.
this._validateOptions();
/**
* A list of the directories the plugin created while copying files. This list exists in order
* to prevent the plugin from trying to create the same directory more than once.
* @type {Array}
* @access protected
* @ignore
*/
this._createdDirectoriesCache = [];
/**
* @ignore
*/
this.onwrite = this.onwrite.bind(this);
}
/**
* Gets the plugin options
* @return {ProjextRollupCopyPluginOptions}
*/
getOptions() {
return this._options;
}
/**
* This is called after Rollup finishes writing the files on the file system. This is where
* the plugin will filter the files that doesn't exist and copy the rest.
* @return {Promise<Array,Error>} The resolved array has the path for each copied file.
*/
onwrite() {
// Reset the _"cache"_.
this._createdDirectoriesCache = [];
return Promise.all(
// Loop all the files to copy.
this._options.files
// Remove those which origin file doesn't exist.
.filter((fileInfo) => fs.pathExistsSync(fileInfo.from))
// Copy the rest...
.map((fileInfo) => {
// Make sure the output directory exists.
this._ensurePath(fileInfo.to);
// _"Copy"_ the file.
return this._copy(fileInfo);
})
);
}
/**
* Valiates the plugin options.
* @throws {Error} If a file doesn't have a `from` and/or `to` property.
* @access protected
* @ignore
*/
_validateOptions() {
const invalid = this._options.files.find((fileInfo) => !fileInfo.from || !fileInfo.to);
if (invalid) {
throw new Error(`${this.name}: All files must have 'from' and 'to' properties`);
}
}
/**
* This is the real method that _"copies"_ a file. If a `transform` property was defined,
* instead of copying the file, it will read it from the source, send it to the transform
* function and then write it on the destination path.
* @param {ProjextRollupCopyPluginItem} fileInfo The information of the file to copy.
* @return {Promise<string,Error>} The resolved value is the path where the file was copied.
* @access protected
* @ignore
*/
_copy(fileInfo) {
// Get the file information.
const { from, to, transform } = fileInfo;
// Get a deferred for the stats entry.
const statsDeferred = deferred();
// Add the deferred promise on the stats.
this._options.stats(statsDeferred.promise);
/**
* If a `transform` property was defined, call the method that handles that, otherwise, just
* copy the file.
*/
const firstStep = transform ?
this._transformFile(fileInfo) :
fs.copy(from, to);

return firstStep
.then(() => {
// Resolve the deferred for the stats entry.
statsDeferred.resolve({
plugin: this.name,
filepath: to,
});
// Resolve the path where the file was copied.
return to;
});
}
/**
* This is called when a file is about to be copied but it has a `transform` property.
* The method will read the file contents, call the function on the `transform` property and
* then write the _"transformed"_ code on the path where the file should be copied.
* @param {ProjextRollupCopyPluginItem} fileInfo The information of the file to copy.
* @return {Promise<undefined,Error>}
* @access protected
* @ignore
*/
_transformFile(fileInfo) {
// Read the file.
return fs.readFile(fileInfo.from)
// _"Transform it"_.
.then((contents) => fileInfo.transform(contents))
// Write the new file.
.then((contents) => fs.writeFile(fileInfo.to, contents));
}
/**
* This is called before trying to copy any file. The method makes sure a path exists so a file
* can be copied. It also checks with the _"internal cache"_ to make sure the directory wasn't
* already created.
* @param {string} filepath A filepath from which the method will take the directory in order to
* verify it exists.
* @access protected
* @ignore
*/
_ensurePath(filepath) {
const directory = path.dirname(filepath);
if (!this._createdDirectoriesCache.includes(directory)) {
this._createdDirectoriesCache.push(directory);
fs.ensureDirSync(directory);
}
}
}
/**
* Shorthand method to create an instance of {@link ProjextRollupCopyPlugin}.
* @param {ProjextRollupCopyPluginOptions} options
* The options to customize the plugin behaviour.
* @param {string} name
* The name of the plugin's instance.
* @return {ProjextRollupCopyPlugin}
*/
const copy = (options, name) => new ProjextRollupCopyPlugin(options, name);

module.exports = {
ProjextRollupCopyPlugin,
copy,
};
17 changes: 15 additions & 2 deletions src/plugins/devServer/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,19 @@ class ProjextRollupDevServerPlugin {
getOptions() {
return this._options;
}
/**
* Gets a _"sub plugin"_ that logs the dev server URL. The idea is to put this at the end of
* the plugins queue so the final feedback the user gets is the URL.
* @return {Object}
*/
showURL() {
return {
onwrite: () => {
// A small _"timeout-hack"_ to show the message after Rollup's output
setTimeout(() => this._logger.success(`Your app is running on ${this.url}`), 0);
},
};
}
/**
* This is called after Rollup finishes writing the files on the file system. It checks if
* there's an instance of the server running and if there isn't, it creates a new one.
Expand All @@ -145,8 +158,8 @@ class ProjextRollupDevServerPlugin {
// Start listening for requests.
this._instance.listen(port);
// Log some information messages.
this._logger.success(`Your app is running on the port ${port}`);
this._logger.info(this.url);
this._logger.warning(`Starting on ${this.url}`);
this._logger.warning('waiting for Rollup...');
// Start listening for process events that require the sever instance to be terminated.
this._startListeningForTermination();
// Open the browser.
Expand Down
2 changes: 2 additions & 0 deletions src/plugins/index.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { compression } = require('./compression');
const { copy } = require('./copy');
const { css } = require('./css');
const { devServer } = require('./devServer');
const { nodeRunner } = require('./nodeRunner');
Expand All @@ -11,6 +12,7 @@ const { windowAsGlobal } = require('./windowAsGlobal');

module.exports = {
compression,
copy,
css,
devServer,
nodeRunner,
Expand Down
8 changes: 7 additions & 1 deletion src/plugins/stats/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,7 @@ class ProjextRollupStatsPlugin {
{
extraEntries: [],
logger: null,
afterLog: null,
},
options
);
Expand All @@ -137,7 +138,12 @@ class ProjextRollupStatsPlugin {
this.add(entry.plugin, entry.filepath);
});
// Log the report table.
return this._logStats();
return this._logStats()
.then(() => {
if (newOptions.afterLog) {
newOptions.afterLog();
}
});
},
};
}
Expand Down
6 changes: 6 additions & 0 deletions src/services/building/configuration.js
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,11 @@ class RollupConfiguration {
output.exports = 'named';
}

const copy = [];
if (target.is.browser || target.bundle) {
copy.push(...this.targets.getFilesToCopy(target, buildType));
}

const params = {
input,
output,
Expand All @@ -92,6 +97,7 @@ class RollupConfiguration {
definitions: this._getDefinitions(target, buildType),
buildType,
paths,
copy,
};

let config = this.targetConfiguration(
Expand Down
14 changes: 12 additions & 2 deletions src/services/configurations/browserDevelopmentConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const json = require('rollup-plugin-json');
const { provider } = require('jimple');
const ConfigurationFile = require('../../abstracts/configurationFile');
const {
copy,
css,
urls,
stylesheetAssets,
Expand Down Expand Up @@ -73,6 +74,14 @@ class RollupBrowserDevelopmentConfiguration extends ConfigurationFile {
params,
statsPlugin.add
);

const statsLogSettings = Object.assign({}, pluginSettings.statsLog);
let devServerInstance;
if (target.runOnDevelopment) {
devServerInstance = devServer(pluginSettings.devServer);
statsLogSettings.afterLog = devServerInstance.showURL().onwrite;
}

// Define the plugins list.
const plugins = [
statsPlugin.reset(),
Expand All @@ -93,7 +102,8 @@ class RollupBrowserDevelopmentConfiguration extends ConfigurationFile {
json(pluginSettings.json),
urls(pluginSettings.urls),
template(pluginSettings.template),
statsPlugin.log(pluginSettings.statsLog),
copy(pluginSettings.copy),
statsPlugin.log(statsLogSettings),
];
// Get the list of external dependencies.
const { external } = pluginSettings.external;
Expand All @@ -114,7 +124,7 @@ class RollupBrowserDevelopmentConfiguration extends ConfigurationFile {
// If the target should run, add the watch settings and push the dev server plugin.
if (target.runOnDevelopment) {
config.watch = pluginSettings.watch;
config.plugins.push(devServer(pluginSettings.devServer));
config.plugins.push(devServerInstance);
}
// Return the reduced configuration.
return this.events.reduce(
Expand Down
2 changes: 2 additions & 0 deletions src/services/configurations/browserProductionConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ const { uglify } = require('rollup-plugin-uglify');
const { provider } = require('jimple');
const ConfigurationFile = require('../../abstracts/configurationFile');
const {
copy,
css,
urls,
stylesheetAssets,
Expand Down Expand Up @@ -94,6 +95,7 @@ class RollupBrowserProductionConfiguration extends ConfigurationFile {
json(pluginSettings.json),
urls(pluginSettings.urls),
uglify(pluginSettings.uglify),
copy(pluginSettings.copy),
];
// If the target is not a library, push the template plugin for the HTML file.
if (!target.library) {
Expand Down
2 changes: 2 additions & 0 deletions src/services/configurations/nodeDevelopmentConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const json = require('rollup-plugin-json');
const { provider } = require('jimple');
const ConfigurationFile = require('../../abstracts/configurationFile');
const {
copy,
css,
urls,
stylesheetAssets,
Expand Down Expand Up @@ -84,6 +85,7 @@ class RollupNodeDevelopmentConfiguration extends ConfigurationFile {
html(pluginSettings.html),
json(pluginSettings.json),
urls(pluginSettings.urls),
copy(pluginSettings.copy),
statsPlugin.log(pluginSettings.statsLog),
];
// Get the list of external dependencies.
Expand Down
2 changes: 2 additions & 0 deletions src/services/configurations/nodeProductionConfiguration.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const json = require('rollup-plugin-json');
const { provider } = require('jimple');
const ConfigurationFile = require('../../abstracts/configurationFile');
const {
copy,
css,
urls,
stats,
Expand Down Expand Up @@ -83,6 +84,7 @@ class RollupNodeProductionConfiguration extends ConfigurationFile {
html(pluginSettings.html),
json(pluginSettings.json),
urls(pluginSettings.urls),
copy(pluginSettings.copy),
statsPlugin.log(pluginSettings.statsLog),
];
// Get the list of external dependencies.
Expand Down
Loading

0 comments on commit 615c9a7

Please sign in to comment.