Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
fedbd52
Merge pull request #1 from parcel-bundler/master
Dec 9, 2017
3f31fc5
Merge branch 'master' of github.com:DeMoorJasper/parcel
DeMoorJasper Dec 9, 2017
b09d15f
Merge pull request #4 from parcel-bundler/master
Dec 11, 2017
80b3431
Merge branch 'master' of github.com:DeMoorJasper/parcel
DeMoorJasper Dec 11, 2017
392bbc9
run prettier
DeMoorJasper Dec 11, 2017
e616cc2
Merge pull request #7 from parcel-bundler/master
Dec 12, 2017
1d90425
stuff
DeMoorJasper Dec 12, 2017
51bfe22
Merge pull request #9 from parcel-bundler/master
Dec 15, 2017
8ad9919
Merge branch 'master' of github.com:DeMoorJasper/parcel
DeMoorJasper Dec 15, 2017
40ea2d8
move config to seperate function
DeMoorJasper Dec 15, 2017
40cffd8
add configHash and versionHash to cache
DeMoorJasper Dec 15, 2017
4c93517
fix json
DeMoorJasper Dec 15, 2017
b721555
fix json
DeMoorJasper Dec 15, 2017
f8ee7bc
fix coffee
DeMoorJasper Dec 15, 2017
96b6668
improve config
DeMoorJasper Dec 15, 2017
9933bac
remove useless line
DeMoorJasper Dec 15, 2017
67b9f9c
cleanup a lil
DeMoorJasper Dec 15, 2017
8920325
remove unused getconfig
DeMoorJasper Dec 15, 2017
43d71f6
bugfix & improvement
DeMoorJasper Dec 16, 2017
528b1e6
Merge branch 'master' into feature/config-cache
Dec 21, 2017
05ca442
fix conflichts
DeMoorJasper Dec 24, 2017
28e7850
Merge branch 'parcel-bundler-master' into feature/config-cache
DeMoorJasper Dec 24, 2017
be60017
Merge branch 'master' into feature/config-cache
Dec 27, 2017
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
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
"babylon": "^6.17.4",
"babylon-walk": "^1.0.2",
"browser-resolve": "^1.11.2",
"canonical-json": "0.0.4",
"chalk": "^2.1.0",
"chokidar": "^1.7.0",
"commander": "^2.11.0",
Expand Down
7 changes: 7 additions & 0 deletions src/Asset.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ class Asset {
this.depAssets = new Map();
this.parentBundle = null;
this.bundles = new Set();
this.config = {};
}

async loadIfNeeded() {
Expand Down Expand Up @@ -90,6 +91,11 @@ class Asset {
return await fs.readFile(this.name, this.encoding);
}

async getConfig() {
// do nothing
return this.config;
}

parse() {
// do nothing by default
}
Expand All @@ -112,6 +118,7 @@ class Asset {

async process() {
if (!this.generated) {
await this.getConfig();
await this.loadIfNeeded();
await this.pretransform();
await this.getDependencies();
Expand Down
32 changes: 31 additions & 1 deletion src/Bundler.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ const Logger = require('./Logger');
const PackagerRegistry = require('./packagers');
const localRequire = require('./utils/localRequire');
const config = require('./utils/config');
const configCache = require('./utils/configCache');
const objectHash = require('./utils/objectHash');
const emoji = require('./utils/emoji');

/**
Expand Down Expand Up @@ -41,6 +43,7 @@ class Bundler extends EventEmitter {
this.errored = false;
this.buildQueue = new Set();
this.rebuildTimeout = null;
this.plugins = [];
}

normalizeOptions(options) {
Expand Down Expand Up @@ -98,6 +101,10 @@ class Bundler extends EventEmitter {
let deps = Object.assign({}, pkg.dependencies, pkg.devDependencies);
for (let dep in deps) {
if (dep.startsWith('parcel-plugin-')) {
this.plugins.push({
name: dep,
version: deps[dep]
});
let plugin = await localRequire(dep, this.mainFile);
plugin(this);
}
Expand Down Expand Up @@ -169,12 +176,27 @@ class Bundler extends EventEmitter {
}
}

async createVersionHash() {
let pkg = await config.load(this.mainFile, ['package.json']);
if (!pkg) {
return '';
}

let versionObject = {
plugins: this.plugins,
version: pkg.version,
name: pkg.name
};
return objectHash(versionObject);
}

async start() {
if (this.farm) {
return;
}

await this.loadPlugins();
this.versionHash = await this.createVersionHash();

this.options.extensions = Object.assign({}, this.parser.extensions);
this.farm = WorkerFarm.getShared(this.options);
Expand Down Expand Up @@ -313,8 +335,16 @@ class Bundler extends EventEmitter {

// First try the cache, otherwise load and compile in the background
let processed = this.cache && (await this.cache.read(asset.name));
if (!processed) {
let sameConfig = false;
if (processed) {
sameConfig = await configCache.compare(asset, processed.configCache);
sameConfig = sameConfig
? processed.versionHash === this.versionHash
: false;
}
if (!processed || !sameConfig) {
processed = await this.farm.run(asset.name, asset.package, this.options);
processed.versionHash = this.versionHash;
if (this.cache) {
this.cache.write(asset.name, processed);
}
Expand Down
8 changes: 7 additions & 1 deletion src/assets/CSSAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class CSSAsset extends Asset {
);
}

async getConfig() {
await postcssTransform.getConfig(this);

return this.config;
}

parse(code) {
let root = postcss.parse(code, {from: this.name, to: this.name});
return new CSSAst(code, root);
Expand Down Expand Up @@ -85,7 +91,7 @@ class CSSAsset extends Asset {
}

async transform() {
await postcssTransform(this);
await postcssTransform.parse(this);
}

getCSSAst() {
Expand Down
8 changes: 7 additions & 1 deletion src/assets/HTMLAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ class HTMLAsset extends Asset {
this.isAstDirty = false;
}

async getConfig() {
await posthtmlTransform.getConfig(this);

return this.config;
}

parse(code) {
let res = parse(code);
res.walk = api.walk;
Expand Down Expand Up @@ -58,7 +64,7 @@ class HTMLAsset extends Asset {
}

async transform() {
await posthtmlTransform(this);
await posthtmlTransform.parse(this);
}

generate() {
Expand Down
20 changes: 11 additions & 9 deletions src/assets/JSAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,13 @@ class JSAsset extends Asset {
);
}

async getParserOptions() {
async getConfig() {
if (this.config.babelOptions && this.config.babelConfig) {
return this.config;
}

// Babylon options. We enable a few plugins by default.
const options = {
this.config.babelOptions = {
filename: this.name,
allowReturnOutsideFunction: true,
allowHashBang: true,
Expand All @@ -48,21 +52,19 @@ class JSAsset extends Asset {
};

// Check if there is a babel config file. If so, determine which parser plugins to enable
this.babelConfig =
this.config.babelConfig =
(this.package && this.package.babel) ||
(await config.load(this.name, ['.babelrc', '.babelrc.js']));
if (this.babelConfig) {
if (this.config.babelConfig) {
const file = new BabelFile({filename: this.name});
options.plugins.push(...file.parserOpts.plugins);
this.config.babelOptions.plugins.push(...file.parserOpts.plugins);
}

return options;
return this.config;
}

async parse(code) {
const options = await this.getParserOptions();

return babylon.parse(code, options);
return babylon.parse(code, this.config.babelOptions);
}

traverse(visitor) {
Expand Down
3 changes: 3 additions & 0 deletions src/assets/JSONAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ class JSONAsset extends JSAsset {
return 'module.exports = ' + (await super.load()) + ';';
}

async getConfig() {
return this.config;
}
parse() {}
collectDependencies() {}
pretransform() {}
Expand Down
28 changes: 20 additions & 8 deletions src/assets/LESSAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,31 @@ const localRequire = require('../utils/localRequire');
const promisify = require('../utils/promisify');

class LESSAsset extends CSSAsset {
async parse(code) {
// less should be installed locally in the module that's being required
let less = await localRequire('less', this.name);
let render = promisify(less.render.bind(less));
async getConfig() {
await super.getConfig();

let opts =
if (this.config.less) {
return this.config;
}

this.config.less =
this.package.less ||
(await config.load(this.name, ['.lessrc', '.lessrc.js'])) ||
{};
opts.filename = this.name;
opts.plugins = (opts.plugins || []).concat(urlPlugin(this));
this.config.less.filename = this.name;
this.config.less.plugins = (this.config.less.plugins || []).concat(
urlPlugin(this)
);

return this.config;
}

async parse(code) {
// less should be installed locally in the module that's being required
let less = await localRequire('less', this.name);
let render = promisify(less.render.bind(less));

let res = await render(code, opts);
let res = await render(code, this.config.less);
res.render = () => res.css;
return res;
}
Expand Down
35 changes: 24 additions & 11 deletions src/assets/SASSAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,23 +5,36 @@ const promisify = require('../utils/promisify');
const path = require('path');

class SASSAsset extends CSSAsset {
async getConfig() {
await super.getConfig();

if (this.config.sass) {
return this.config;
}

this.config.sass =
this.package.sass ||
(await config.load(this.name, ['.sassrc', '.sassrc.js'])) ||
{};
this.config.sass.includePaths = (
this.config.sass.includePaths || []
).concat(path.dirname(this.name));

this.config.sass.indentedSyntax =
typeof this.config.sass.indentedSyntax === 'boolean'
? this.config.sass.indentedSyntax
: path.extname(this.name).toLowerCase() === '.sass';

return this.config;
}

async parse(code) {
// node-sass should be installed locally in the module that's being required
let sass = await localRequire('node-sass', this.name);
let render = promisify(sass.render.bind(sass));

let opts =
this.package.sass ||
(await config.load(this.name, ['.sassrc', '.sassrc.js'])) ||
{};
opts.includePaths = (opts.includePaths || []).concat(
path.dirname(this.name)
);
let opts = this.config.sass;
opts.data = code;
opts.indentedSyntax =
typeof opts.indentedSyntax === 'boolean'
? opts.indentedSyntax
: path.extname(this.name).toLowerCase() === '.sass';

opts.functions = Object.assign({}, opts.functions, {
url: node => {
Expand Down
19 changes: 15 additions & 4 deletions src/assets/StylusAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,24 @@ const Resolver = require('../Resolver');
const URL_RE = /^(?:url\s*\(\s*)?['"]?(?:[#/]|(?:https?:)?\/\/)/i;

class StylusAsset extends CSSAsset {
async getConfig() {
await super.getConfig();

if (this.config.stylus) {
return this.config;
}

this.config.stylus =
this.package.stylus ||
(await config.load(this.name, ['.stylusrc', '.stylusrc.js']));

return this.config;
}

async parse(code) {
// stylus should be installed locally in the module that's being required
let stylus = await localRequire('stylus', this.name);
let opts =
this.package.stylus ||
(await config.load(this.name, ['.stylusrc', '.stylusrc.js']));
let style = stylus(code, opts);
let style = stylus(code, this.config.stylus);
style.set('filename', this.name);
style.set('include css', true);
style.set('Evaluator', await createEvaluator(this));
Expand Down
28 changes: 20 additions & 8 deletions src/assets/TypeScriptAsset.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ const config = require('../utils/config');
const localRequire = require('../utils/localRequire');

class TypeScriptAsset extends JSAsset {
async parse(code) {
// require typescript, installed locally in the app
async getConfig() {
await super.getConfig();
let typescript = await localRequire('typescript', this.name);
let transpilerOptions = {

if (this.config.typescript) {
return this.config;
}

this.config.typescript = {
compilerOptions: {
module: typescript.ModuleKind.CommonJS,
jsx: typescript.JsxEmit.Preserve
Expand All @@ -18,19 +23,26 @@ class TypeScriptAsset extends JSAsset {

// Overwrite default if config is found
if (tsconfig) {
transpilerOptions.compilerOptions = Object.assign(
transpilerOptions.compilerOptions,
this.config.typescript.compilerOptions = Object.assign(
this.config.typescript.compilerOptions,
tsconfig.compilerOptions
);
}
transpilerOptions.compilerOptions.noEmit = false;
this.config.typescript.compilerOptions.noEmit = false;

return this.config.typescript;
}

async parse(code) {
let typescript = await localRequire('typescript', this.name);

// Transpile Module using TypeScript and parse result as ast format through babylon
this.contents = typescript.transpileModule(
code,
transpilerOptions
this.config.typescript
).outputText;
return await super.parse(this.contents);

return super.parse(this.contents);
}
}

Expand Down
6 changes: 3 additions & 3 deletions src/transforms/babel.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
const babel = require('babel-core');
const config = require('../utils/config');

module.exports = async function(asset) {
if (!await shouldTransform(asset)) {
Expand Down Expand Up @@ -30,13 +29,14 @@ async function shouldTransform(asset) {
}

if (asset.ast) {
return !!asset.babelConfig;
return !!asset.config.babelConfig;
}

if (asset.package && asset.package.babel) {
return true;
}

let babelrc = await config.resolve(asset.name, ['.babelrc', '.babelrc.js']);
await asset.getConfig();
let babelrc = asset.config.babelConfig;
return !!babelrc;
}
Loading