Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[TIMOB-25768] Implement ability to use rollup #24

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
62 changes: 52 additions & 10 deletions lib/jsanalyze.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@

var appc = require('node-appc'),
fs = require('fs'),
path = require('path'),
DOMParser = require('xmldom').DOMParser,
babel = require('babel-core'),
babel = require('@babel/core'),
babylon = require('babylon'),
types = require('babel-types'),
traverse = require('babel-traverse').default,
babili = require.resolve('babel-preset-babili'),
env = require('babel-preset-env'),
types = require('@babel/types'),
traverse = require('@babel/traverse').default,
minify = require('babel-preset-minify'),
env = require('@babel/preset-env'),
rollup = require('rollup'),
resolver = require('rollup-plugin-resolver'),
regenerator = require.resolve('regenerator-runtime'),
__ = appc.i18n(__dirname).__,
apiUsage = {};

Expand Down Expand Up @@ -97,7 +101,7 @@ function getTitaniumExpression(member) {
* @returns {Object} An object containing symbols and minified JavaScript
* @throws {Error} An error if unable to parse the JavaScript
*/
exports.analyzeJs = function analyzeJs(contents, opts) {
exports.analyzeJs = async function analyzeJs(contents, opts) {
var ast,
symbols = {},
results = {
Expand Down Expand Up @@ -171,6 +175,7 @@ exports.analyzeJs = function analyzeJs(contents, opts) {
// transpile
if (opts.transpile) {
options.presets.push([ env, { targets: opts.targets } ]);
options.plugins.push(require.resolve('@babel/plugin-transform-async-to-generator'));
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I assume this plus the regenerator runtime are required to support async/await?

}

// minify
Expand All @@ -181,16 +186,53 @@ exports.analyzeJs = function analyzeJs(contents, opts) {
comments: false
});

options.presets.push([ babili, {
options.presets.push([ minify, {
mangle: false,
deadcode: false
deadcode: false,
removeUndefined: false
} ]);

options.plugins.push(require.resolve('babel-plugin-transform-property-literals'));
options.plugins.push(require.resolve('@babel/plugin-transform-property-literals'));
}

if (options.presets.length) {
// FIXME we can't re-use the ast here, because we traversed it

// rollup is required to workaround circular references unsupported by JavascriptCore
// this should only run on 'app.js', bundling all dependencies into one file
if (opts.rollup) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the ability to include rollup in the pipeline is interesting and useful, but seems like a huge new addition here that we need to test/try out a bit before I'd feel too comfortable.

I assume the driver here was using ES6 imports with circular references on iOS?

Rollup should only be run on the single app entry point, and would be akin to minification in my mind.

I think we're quickly bumping into a large architectural issue here:

  • We need to find a way to be able to run some arbitrary set of transformations on the app source code
  • in a way that doesn't clash with one another
  • with the output of one transformation being the input to the next (i.e the modified source and source map).

let input = {
[opts.filename]: contents
};

// include regenerator-runtime needed for async support
if (opts.rollup.runtime) {
const runtimePath = path.join(path.dirname(regenerator), 'runtime.js');
input[opts.filename] = `import 'runtime';${contents}`;
input.runtime = fs.readFileSync(runtimePath).toString();
}

// configure rollup
const bundle = await rollup.rollup({
input: input,
context: `'${path.join(opts.projectDir, 'Resources')}'`,
plugins: [
resolver()
]
});

// generate code and a source map
// TODO: make use of source map
const { code, map } = await bundle.generate({
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My concern here is that babel has generated bad source maps in the past for us, so I've been trying to work around the issue by using the retainLines: true option whenever we pass through babel.

Studio uses the source maps for debugging, but we've found out the hard way that babel's source map generation is not reliable. (We consume alloy's source maps)

It looks as though rollup actually uses acorn, not babel - so maybe it's more reliable?

We need to actually look for and combine the possible alloy source map into the process too.

format: 'cjs',
globals: {
Titanium: 'Titanium',
Ti: 'Ti'
}
});
contents = code;
}

// transpile
results.contents = babel.transform(contents, options).code;
}

Expand Down
Loading