From 93a0489eae8810c705d9fb09ed126642a6cf96aa Mon Sep 17 00:00:00 2001 From: Mario Campa Date: Tue, 14 Mar 2017 17:49:43 -0700 Subject: [PATCH 1/4] STENCIL-3243 run the theme bundling script (webpack) in a different process (fork) & fix a bunch of tests --- bin/stencil-bundle | 8 +- bin/stencil-bundle.spec.js | 139 +++++++++--------- bin/stencil-init.spec.js | 76 +++++----- bin/stencil-start | 39 ++--- lib/release/release.js | 6 +- lib/stencil-build-config.js | 92 ++++++++++++ lib/stencil-build-config.spec.js | 73 +++++++++ lib/stencil-bundle.js | 14 +- package.json | 4 +- {lib => server/lib}/stencil-token.spec.js | 0 .../legacy-config/stencil.conf.js | 41 ++++++ .../noready-config/stencil.conf.js | 52 +++++++ .../noworker-config/stencil.conf.js | 1 + .../build-config/valid-config/stencil.conf.js | 52 +++++++ 14 files changed, 447 insertions(+), 150 deletions(-) create mode 100644 lib/stencil-build-config.js create mode 100644 lib/stencil-build-config.spec.js rename {lib => server/lib}/stencil-token.spec.js (100%) create mode 100644 test/_mocks/build-config/legacy-config/stencil.conf.js create mode 100644 test/_mocks/build-config/noready-config/stencil.conf.js create mode 100644 test/_mocks/build-config/noworker-config/stencil.conf.js create mode 100644 test/_mocks/build-config/valid-config/stencil.conf.js diff --git a/bin/stencil-bundle b/bin/stencil-bundle index 2f37c4fa..fdd107e1 100755 --- a/bin/stencil-bundle +++ b/bin/stencil-bundle @@ -11,8 +11,6 @@ var themePath = process.cwd(); var configuration; var bundle; var Bundle = require('../lib/stencil-bundle'); -var stencilConfig; -var stencilConfigFilePath = Path.join(themePath, 'stencil.conf.js'); var themeConfig; var versionCheck = require('../lib/version-check'); @@ -29,10 +27,6 @@ if (!versionCheck()) { themeConfig = ThemeConfig.getInstance(themePath); -if (fileExist(stencilConfigFilePath)) { - stencilConfig = require(stencilConfigFilePath); -} - if (Program.dest === true) { return console.error('Error: You have to specify a value for -d or --dest'.red); } @@ -47,7 +41,7 @@ if (!themeConfig.configExists()) { configuration = themeConfig.getRawConfig(); -bundle = new Bundle(themePath, themeConfig, configuration, stencilConfig, { +bundle = new Bundle(themePath, themeConfig, configuration, { marketplace: Program.marketplace, dest: Program.dest, name: Program.name, diff --git a/bin/stencil-bundle.spec.js b/bin/stencil-bundle.spec.js index 2dd52d7f..43e126c4 100644 --- a/bin/stencil-bundle.spec.js +++ b/bin/stencil-bundle.spec.js @@ -1,50 +1,57 @@ -var Code = require('code'); -var Fs = require('fs'); -var Sinon = require('sinon'); -var rewire = require('rewire'); -var Path = require('path'); -var async = require('async'); -var when = require('when'); -var Lab = require('lab'); -var lab = exports.lab = Lab.script(); -var describe = lab.describe; -var themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); -var expect = Code.expect; -var it = lab.it; -var StencilBundle = rewire('../lib/stencil-bundle'); -var bundleValidator = require('../lib/bundle-validator'); -var AsyncStub; -var jspm = require('jspm'); -var themeConfigStub; -var rawConfig; -var themeSchema = Fs.readFileSync((Path.join(themePath, 'schema.json'))).toString(); -var Bundle; - -describe('Stencil Bundle', function () { - - lab.beforeEach(function (done) { - +'use strict'; + +const Code = require('code'); +const Fs = require('fs'); +const Sinon = require('sinon'); +const rewire = require('rewire'); +const Path = require('path'); +const async = require('async'); +const when = require('when'); +const Lab = require('lab'); +const lab = exports.lab = Lab.script(); +const describe = lab.describe; +const themePath = Path.join(process.cwd(), 'test/_mocks/themes/valid'); +const expect = Code.expect; +const it = lab.it; +const StencilBundle = rewire('../lib/stencil-bundle'); +const bundleValidator = require('../lib/bundle-validator'); +const jspm = require('jspm'); +const themeSchema = Fs.readFileSync((Path.join(themePath, 'schema.json'))).toString(); + +describe('Stencil Bundle', () => { + let sandbox; + let rawConfig; + let Bundle; + let AsyncStub; + let themeConfigStub; + + lab.beforeEach(done => { + sandbox = Sinon.sandbox.create(); themeConfigStub = getThemeConfigStub(); rawConfig = { "name": "Cornerstone", "version": "1.1.0", }; - Bundle = new StencilBundle(themePath, themeConfigStub, rawConfig, null, { + sandbox.stub(console, 'log'); + sandbox.stub(console, 'error'); + + Bundle = new StencilBundle(themePath, themeConfigStub, rawConfig, { marketplace: false, }); done(); }); - lab.afterEach(function (done) { + lab.afterEach(done => { AsyncStub.restore(); + sandbox.restore(); done(); }); - it('should initialize bundling', function (done) { + it('should initialize bundling', done => { AsyncStub = Sinon.stub(async, 'series'); AsyncStub.callsArgWith(1, new Error('error')); - var throws = function () { + const throws = () => { Bundle.initBundle(); }; @@ -54,44 +61,44 @@ describe('Stencil Bundle', function () { done(); }); - it('should assemble CSS files', function (done) { + it('should assemble CSS files', done => { AsyncStub = Sinon.stub(async, 'map'); AsyncStub.callsArgWith(2, null, ['this is dog']); - var callback = function (err, result) { + const callback = (err, result) => { expect(result).to.deep.equal({'theme.scss': 'this is dog'}); AsyncStub.restore(); done(); }; - var task = Bundle.getCssAssembleTask('scss'); + const task = Bundle.getCssAssembleTask('scss'); task(callback); }); - it('should error on assemble CSS files', function (done) { + it('should error on assemble CSS files', done => { AsyncStub = Sinon.stub(async, 'map'); AsyncStub.callsArgWith(2, 'error'); - var callback = function (err, result) { + const callback = (err, result) => { expect(err).to.equal('error'); AsyncStub.restore(); done(); }; - var task = Bundle.getCssAssembleTask('scss'); + const task = Bundle.getCssAssembleTask('scss'); task(callback); }); - it('should assembleTemplates', function (done) { + it('should assembleTemplates', done => { AsyncStub = Sinon.stub(async, 'map'); AsyncStub.callsArgWith(2, null, ['test', 'test2']); - var BundleVal = Sinon.stub(bundleValidator.prototype, 'validateObjects').callsArgWith(1, null); + const BundleVal = Sinon.stub(bundleValidator.prototype, 'validateObjects').callsArgWith(1, null); - var callback = function (err, result) { + const callback = (err, result) => { expect(result).to.deep.equal({page: 'test', page2: 'test2'}); AsyncStub.restore(); BundleVal.restore(); @@ -102,12 +109,12 @@ describe('Stencil Bundle', function () { }); - it('should error when running assembleTemplates', function (done) { + it('should error when running assembleTemplates', done => { AsyncStub = Sinon.stub(async, 'map'); AsyncStub.callsArgWith(2, 'error'); - var BundleVal = Sinon.stub(bundleValidator.prototype, 'validateObjects').callsArgWith(1, null); + const BundleVal = Sinon.stub(bundleValidator.prototype, 'validateObjects').callsArgWith(1, null); - var callback = function (err, result) { + const callback = (err, result) => { expect(err).to.equal('error'); AsyncStub.restore(); BundleVal.restore(); @@ -118,8 +125,8 @@ describe('Stencil Bundle', function () { }); - it('should assemble the Schema', function (done) { - var callback = function (err, result) { + it('should assemble the Schema', done => { + const callback = (err, result) => { expect(result).to.deep.equal(themeSchema); done(); }; @@ -128,15 +135,15 @@ describe('Stencil Bundle', function () { }); - it('should assemble the Lang Files', function (done) { - var langStub = Sinon.stub(); + it('should assemble the Lang Files', done => { + const langStub = Sinon.stub(); langStub.assemble = Sinon.stub().callsArgWith(0, null); StencilBundle.__set__({ 'LangAssembler': langStub }); - var callback = function () { + const callback = () => { expect(langStub.assemble.calledOnce).to.equal(true); done(); }; @@ -145,15 +152,15 @@ describe('Stencil Bundle', function () { }); - it('should error on assembling the Lang Files', function (done) { - var langStub = Sinon.stub(); + it('should error on assembling the Lang Files', done => { + const langStub = Sinon.stub(); langStub.assemble = Sinon.stub().callsArgWith(0, 'error'); StencilBundle.__set__({ 'LangAssembler': langStub }); - var callback = function (err) { + const callback = (err) => { expect(langStub.assemble.calledOnce).to.equal(true); expect(err).to.equal('error'); done(); @@ -163,10 +170,10 @@ describe('Stencil Bundle', function () { }); - it('should bundle JSPM assets', function (done) { - var jspmStub = Sinon.stub(jspm, 'bundleSFX').returns(when()); + it('should bundle JSPM assets', done => { + const jspmStub = Sinon.stub(jspm, 'bundleSFX').returns(when()); - var callback = function (err, result) { + const callback = (err, result) => { expect(result).to.equal(true); jspmStub.restore(); done(); @@ -176,10 +183,10 @@ describe('Stencil Bundle', function () { }); - it('should fail to bundle JSPM assets', function (done) { - var jspmStub = Sinon.stub(jspm, 'bundleSFX').returns(when.reject(false)); + it('should fail to bundle JSPM assets', done => { + const jspmStub = Sinon.stub(jspm, 'bundleSFX').returns(when.reject(false)); - var callback = function (err) { + const callback = (err) => { expect(err).to.equal(false); jspmStub.restore(); done(); @@ -188,16 +195,16 @@ describe('Stencil Bundle', function () { Bundle.getJspmBundleTask(getThemeConfigStub().getRawConfig)(callback); }); - it('should generate a manifest of files.', function (done) { - var rrStub = Sinon.stub().callsArgWith(2, null, ['test', 'test2']); - var FsStub = Sinon.stub().callsArgWith(2, null); + it('should generate a manifest of files.', done => { + const rrStub = Sinon.stub().callsArgWith(2, null, ['test', 'test2']); + const FsStub = Sinon.stub().callsArgWith(2, null); StencilBundle.__set__({ 'rr': rrStub, 'Fs.writeFile': FsStub }); - var callback = function () { + const callback = () => { expect(rrStub.calledOnce).to.equal(true); expect(Bundle.manifest.templates[0]).to.equal('test'); expect(Bundle.manifest.templates[1]).to.equal('test2'); @@ -208,16 +215,16 @@ describe('Stencil Bundle', function () { Bundle.generateManifest(callback); }); - it('should error while reading files to generate a manifest of files.', function (done) { - var rrStub = Sinon.stub().callsArgWith(2, 'There was an error', null); - var FsStub = Sinon.stub().callsArgWith(2, null); + it('should error while reading files to generate a manifest of files.', done => { + const rrStub = Sinon.stub().callsArgWith(2, 'There was an error', null); + const FsStub = Sinon.stub().callsArgWith(2, null); StencilBundle.__set__({ 'rr': rrStub, 'Fs.writeFile': FsStub }); - var callback = function (err, result) { + const callback = (err, result) => { expect(rrStub.calledOnce).to.equal(true); expect(FsStub.calledOnce).to.equal(false); expect(err).to.equal('There was an error'); @@ -229,8 +236,8 @@ describe('Stencil Bundle', function () { }); function getThemeConfigStub() { - var themeConfig = Sinon.stub(); - var rawConfig = { + const themeConfig = Sinon.stub(); + const rawConfig = { jspm: { dev: { dep_location: 'assets/js/dependency-bundle.js', diff --git a/bin/stencil-init.spec.js b/bin/stencil-init.spec.js index 42b56512..91ac0ddb 100644 --- a/bin/stencil-init.spec.js +++ b/bin/stencil-init.spec.js @@ -1,41 +1,37 @@ -var Code = require('code'); -var Fs = require('fs'); -var Sinon = require('sinon'); -var Lab = require('lab'); -var lab = exports.lab = Lab.script(); -var describe = lab.describe; -var Inquirer = require('inquirer'); -var expect = Code.expect; -var it = lab.it; -var StencilInit = require('../lib/stencil-init'); - -/** - * Gets jspm assembler stub - * - * @returns Sinon - */ -function getJspmAssemblerStub() { - var jspmAssembler = Sinon.stub(); - return jspmAssembler; -} - -/** - * Gets theme config spy - * - * @returns Sinon - */ -function getThemeConfigStub() { - var themeConfig = Sinon.spy(); - return themeConfig; -} - -describe('stencil init', function() { +'use strict'; + +const Code = require('code'); +const Fs = require('fs'); +const Sinon = require('sinon'); +const Lab = require('lab'); +const lab = exports.lab = Lab.script(); +const describe = lab.describe; +const Inquirer = require('inquirer'); +const expect = Code.expect; +const it = lab.it; +const StencilInit = require('../lib/stencil-init'); + +describe('stencil init', () => { + let sandbox; + + lab.beforeEach(done => { + sandbox = Sinon.sandbox.create(); + sandbox.stub(console, 'log'); + sandbox.stub(console, 'error'); + done(); + }); + + lab.afterEach(done => { + sandbox.restore(); + done(); + }); + var inquirer = Sinon.spy(Inquirer, 'prompt'); - it('should call prompt', function(done) { - var dotStencilFile = '../_mocks/bin/dotStencilFile.json'; - var jspmAssembler = getJspmAssemblerStub(); - var themeConfig = getThemeConfigStub(); + it('should call prompt', done => { + const dotStencilFile = '../_mocks/bin/dotStencilFile.json'; + const jspmAssembler = Sinon.stub(); + const themeConfig = Sinon.spy(); StencilInit(jspmAssembler, themeConfig, dotStencilFile); @@ -44,10 +40,10 @@ describe('stencil init', function() { done(); }); - it('should not call prompt with bad JSON from dotStencilFile', function(done) { - var dotStencilFile = '../_mocks/malformedSchema.json'; - var jspmAssembler = getJspmAssemblerStub(); - var themeConfig = getThemeConfigStub(); + it('should not call prompt with bad JSON from dotStencilFile', done => { + const dotStencilFile = '../_mocks/malformedSchema.json'; + const jspmAssembler = Sinon.stub(); + const themeConfig = Sinon.spy(); StencilInit(jspmAssembler, themeConfig, dotStencilFile); diff --git a/bin/stencil-start b/bin/stencil-start index 0536cf16..38a2d424 100755 --- a/bin/stencil-start +++ b/bin/stencil-start @@ -13,6 +13,7 @@ var Pkg = require('../package.json'); var Program = require('commander'); var Server = require('../server'); var ThemeConfig = require('../lib/theme-config'); +var buildConfig = require('../lib/stencil-build-config'); var stencilToken = require('../server/lib/stencil-token'); var Url = require('url'); var Wreck = require('wreck'); @@ -25,12 +26,10 @@ var cssCompilerDir; var cssWatchBaseDir = Path.join(themePath, 'assets/'); var templatePath = Path.join(themePath, 'templates'); var dotStencilFilePath = Path.join(themePath, '.stencil'); -var stencilConfigFilePath = Path.join(themePath, 'stencil.conf.js'); var themeConfigPath = Path.join(themePath, 'config.json'); var dotStencilFile; var isTopLevelCssRegex; var stencilServerPort; -var stencilConfig; var themeConfig; var configuration; var staplerUrl; @@ -57,10 +56,6 @@ if (!fileExist(dotStencilFilePath)) { return console.error('Error: Please run'.red + ' $ stencil init'.cyan + ' first.'.red); } -if (fileExist(stencilConfigFilePath)) { - stencilConfig = require(stencilConfigFilePath); -} - if (!fileExist(Path.join(themePath, 'config.json'))) { return console.error('Error: You must have a '.red + 'config.json'.cyan + ' file in your top level theme directory.'); } @@ -220,7 +215,7 @@ function startServer() { * When a file in a sub directory changes, we have to recompile all top level files because * more than one could have included the changed file. */ - Bs.watch(cssCompilerDir, function (event, file) { + Bs.watch(cssCompilerDir, (event, file) => { var relativePath, changedFile, basename; @@ -241,7 +236,7 @@ function startServer() { } }); - Bs.watch('config.json', function (event) { + Bs.watch('config.json', (event) => { if (event === 'change') { try { configuration = themeConfig.getConfig(); @@ -253,8 +248,8 @@ function startServer() { } }); - Bs.watch(templatePath, {ignoreInitial: true}, function () { - assembleTemplates(templatePath, function(err, results) { + Bs.watch(templatePath, {ignoreInitial: true}, () => { + assembleTemplates(templatePath, (err, results) => { if (err) { return console.error(err); } @@ -267,35 +262,31 @@ function startServer() { }) }); - if (stencilConfig && stencilConfig.watchOptions && stencilConfig.watchOptions.files) { - watchFiles = stencilConfig.watchOptions.files; + if (buildConfig.watchOptions && buildConfig.watchOptions.files) { + watchFiles = buildConfig.watchOptions.files; } - if (stencilConfig && stencilConfig.watchOptions && stencilConfig.watchOptions.ignored) { - watchIgnored = stencilConfig.watchOptions.ignored; + if (buildConfig.watchOptions && buildConfig.watchOptions.ignored) { + watchIgnored = buildConfig.watchOptions.ignored; } Bs.init({ open: !!Program.open, port: browserSyncPort, - files: watchFiles.map(function (val) { - return Path.join(themePath, val); - }), + files: watchFiles.map(val => Path.join(themePath, val)), watchOptions: { ignoreInitial: true, - ignored: watchIgnored.map(function (val) { - return Path.join(themePath, val); - }) + ignored: watchIgnored.map(val => Path.join(themePath, val)), }, proxy: "localhost:" + stencilServerPort, - tunnel: !!Program.tunnel + tunnel: !!Program.tunnel, }); // Handle manual reloading of browsers by typing 'rs'; // Borrowed from https://github.com/remy/nodemon process.stdin.resume(); process.stdin.setEncoding('utf8'); - process.stdin.on('data', function (data) { + process.stdin.on('data', data => { data = (data + '').trim().toLowerCase(); // if the keys entered match the restartable value, then restart! @@ -305,8 +296,8 @@ function startServer() { }); }); - if (stencilConfig && typeof(stencilConfig.development) === 'function') { - stencilConfig.development(Bs); + if (buildConfig.development) { + buildConfig.development(() => Bs.reload()); } } diff --git a/lib/release/release.js b/lib/release/release.js index f3330e9d..b2159b52 100644 --- a/lib/release/release.js +++ b/lib/release/release.js @@ -201,12 +201,10 @@ function getGithubToken() { } function bundleTheme(callback) { - const stencilConfig = require(path.join(themePath, 'stencil.conf.js')); - const bundleOptions = { + const bundle = new Bundle(themePath, themeConfig, themeConfig.getRawConfig(), { dest: os.tmpdir(), name: uuid(), - }; - const bundle = new Bundle(themePath, themeConfig, themeConfig.getRawConfig(), stencilConfig, bundleOptions); + }); bundle.initBundle(callback); } diff --git a/lib/stencil-build-config.js b/lib/stencil-build-config.js new file mode 100644 index 00000000..94bd43bf --- /dev/null +++ b/lib/stencil-build-config.js @@ -0,0 +1,92 @@ +'use strict'; + +const _ = require('lodash'); +const fork = require('child_process').fork; +const Path = require('path'); +const Fs = require('fs'); +const buildConfigPath = Path.join(process.cwd(), 'stencil.conf.js'); +const worker = getWorker(); +const config = getConfig(); + +const onReadyCallbacks = []; +let workerIsReady = false; + +function getConfig() { + let config = {}; + + if (Fs.existsSync(buildConfigPath)) { + config = require(buildConfigPath); + } + + return config; +} + +function getWorker() { + let worker = null; + + if (Fs.existsSync(buildConfigPath)) { + worker = fork(buildConfigPath, [], { cwd: process.cwd() }); + + worker.on('message', message => { + if (message === 'ready') { + workerIsReady = true; + onReadyCallbacks.forEach(callback => callback()); + } + }); + } + + return worker; +} + +function onWorkerReady(onReady) { + if (workerIsReady) { + process.nextTick(onReady); + } + + onReadyCallbacks.push(onReady); +} + +function devWorker(reload) { + if (!worker) { + return; + } + // send a message to the worker to start watching + // and wait for message to reload the browser + worker.send('development'); + worker.on('message', message => { + if (message === 'reload') { + reload(); + } + }); +} + +function prodWorker(done) { + const callback = _.once(done); + + if (!worker) { + return process.nextTick(() => callback('noworker')); + } + + const timeout = setTimeout(() => callback('timeout'), 1000); + + onWorkerReady(() => { + clearTimeout(timeout); + // send a message to the worker to start bundling js + worker.send('production'); + worker.on('message', message => { + if (message === 'done') { + worker.kill(); + callback(); + } + }); + }); + + worker.on('close', () => callback('noworker')); +} + + +module.exports = { + watchOptions: config.watchOptions, + development: config.development || devWorker, + production: config.production || prodWorker, +}; diff --git a/lib/stencil-build-config.spec.js b/lib/stencil-build-config.spec.js new file mode 100644 index 00000000..6bfa8d39 --- /dev/null +++ b/lib/stencil-build-config.spec.js @@ -0,0 +1,73 @@ +'use strict'; + +const Code = require('code'); +const Lab = require('lab'); +const sinon = require('sinon'); +const lab = exports.lab = Lab.script(); +const describe = lab.describe; +const expect = Code.expect; +const it = lab.it; +const cwd = process.cwd(); + +describe('stencilBuildConfig', () => { + let sandbox; + let buildConfig; + + function loadModule(mockName) { + const path = `${cwd}/test/_mocks/build-config/${mockName}`; + delete require.cache[require.resolve('./stencil-build-config')]; + sandbox.stub(process, 'cwd').returns(path); + + return require('./stencil-build-config'); + } + + lab.beforeEach(done => { + sandbox = sinon.sandbox.create(); + done(); + }); + + lab.afterEach(done => { + sandbox.restore(); + done(); + }); + + it('should return watchOptions', done => { + const buildConfig = loadModule('valid-config'); + + expect(buildConfig.watchOptions).to.be.an.object(); + expect(buildConfig.watchOptions.files).to.be.an.array(); + expect(buildConfig.watchOptions.ignored).to.be.an.array(); + + done(); + }); + + it('should call "done()" function when production bundle finishes', done => { + const buildConfig = loadModule('valid-config'); + + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.be.undefined(); + done(); + }); + }); + + it('should call "done()" function when production bundle finishes (legacy-config)', done => { + const buildConfig = loadModule('legacy-config'); + + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.be.undefined(); + done(); + }); + }); + + it('should call done with "noworker" meesage', done => { + const buildConfig = loadModule('noworker-config'); + + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.equal('noworker'); + done(); + }); + }); +}); diff --git a/lib/stencil-bundle.js b/lib/stencil-bundle.js index 45864ab3..2e47532f 100644 --- a/lib/stencil-bundle.js +++ b/lib/stencil-bundle.js @@ -10,6 +10,7 @@ var Crypto = require('crypto'); var Fs = require('fs'); var Jspm = require('jspm'); var Path = require('path'); +var buildConfig = require('../lib/stencil-build-config'); var BundleValidator = require('./bundle-validator'); var Cycles = require('./cycles'); var CssAssembler = require('./css-assembler'); @@ -17,14 +18,13 @@ var LangAssembler = require('./lang-assembler'); var TemplateAssembler = require('./template-assembler'); var validator; -function Bundle(themePath, themeConfig, rawConfig, stencilConfig, options) { +function Bundle(themePath, themeConfig, rawConfig, options) { var tasks = {}; this.options = options || {}; this.templatesBasePath = Path.join(themePath, 'templates'); this.themePath = themePath; this.themeConfig = themeConfig; - this.stencilConfig = stencilConfig || {}; this.configuration = rawConfig; this.manifest = {}; validator = new BundleValidator(this.themePath, this.themeConfig, this.options.marketplace !== true); @@ -38,11 +38,11 @@ function Bundle(themePath, themeConfig, rawConfig, stencilConfig, options) { tasks.schema = this.assembleSchema.bind(this); tasks.manifest = this.generateManifest.bind(this); - if (this.stencilConfig && typeof(this.stencilConfig.production) === 'function') { - tasks.custom = function (callback) { - console.log('Theme custom task Started...'); - stencilConfig.production(function (error) { - console.log('ok'.green + ' -- Theme custom task Finished'); + if (typeof buildConfig.production === 'function') { + tasks.theme = callback => { + console.log('Theme task Started...'); + buildConfig.production(() => { + console.log('ok'.green + ' -- Theme task Finished'); callback(); }); } diff --git a/package.json b/package.json index 321098f0..07de75e2 100644 --- a/package.json +++ b/package.json @@ -7,8 +7,8 @@ "node": ">= 4.0.0" }, "scripts": { - "test": "lab server -t 80 -l -e 'development' -P spec", - "test-cov-html": "lab server -r html -o coverage.html -P spec" + "test": "lab bin/ server/ lib/ -t 80 -l -e 'development' -P spec", + "test-cov-html": "lab bin/ server/ lib/ -r html -o coverage.html -P spec" }, "bin": { "stencil": "./bin/stencil", diff --git a/lib/stencil-token.spec.js b/server/lib/stencil-token.spec.js similarity index 100% rename from lib/stencil-token.spec.js rename to server/lib/stencil-token.spec.js diff --git a/test/_mocks/build-config/legacy-config/stencil.conf.js b/test/_mocks/build-config/legacy-config/stencil.conf.js new file mode 100644 index 00000000..4629bb5d --- /dev/null +++ b/test/_mocks/build-config/legacy-config/stencil.conf.js @@ -0,0 +1,41 @@ +/** + * Watch options for the core watcher + * @type {{files: string[], ignored: string[]}} + */ +var watchOptions = { + // If files in these directories change, reload the page. + files: [ + '/templates', + '/lang', + ], + + //Do not watch files in these directories + ignored: [ + '/assets/scss', + '/assets/less', + '/assets/css', + '/assets/dist', + ] +}; + +/** + * Watch any custom files and trigger a rebuild + */ +function development(Bs) { + // Rebuild the bundle once at bootup + setTimeout(() => { + Bs.reload(); + }); +} + +/** + * Hook into the `stencil bundle` command and build your files before they are packaged as a .zip + */ +function production(done) { + // Rebuild the bundle once at bootup + setTimeout(() => { + done(); + }); +} + +module.exports = { watchOptions, development, production }; diff --git a/test/_mocks/build-config/noready-config/stencil.conf.js b/test/_mocks/build-config/noready-config/stencil.conf.js new file mode 100644 index 00000000..aece7f93 --- /dev/null +++ b/test/_mocks/build-config/noready-config/stencil.conf.js @@ -0,0 +1,52 @@ +/** + * Watch options for the core watcher + * @type {{files: string[], ignored: string[]}} + */ +var watchOptions = { + // If files in these directories change, reload the page. + files: [ + '/templates', + '/lang', + ], + + //Do not watch files in these directories + ignored: [ + '/assets/scss', + '/assets/less', + '/assets/css', + '/assets/dist', + ] +}; + +/** + * Watch any custom files and trigger a rebuild + */ +function development() { + // Rebuild the bundle once at bootup + setTimeout(() => process.send('reload'), 10); +} + +/** + * Hook into the `stencil bundle` command and build your files before they are packaged as a .zip + */ +function production() { + // Rebuild the bundle once at bootup + setTimeout(() => process.send('done'), 10); +} + +if (process.send) { + // running as a forked worker + process.on('message', message => { + if (message === 'development') { + development(); + } + + if (message === 'production') { + production(); + } + }); + + // process.send('ready'); +} + +module.exports = { watchOptions }; diff --git a/test/_mocks/build-config/noworker-config/stencil.conf.js b/test/_mocks/build-config/noworker-config/stencil.conf.js new file mode 100644 index 00000000..a2d189f6 --- /dev/null +++ b/test/_mocks/build-config/noworker-config/stencil.conf.js @@ -0,0 +1 @@ +module.exports = { }; diff --git a/test/_mocks/build-config/valid-config/stencil.conf.js b/test/_mocks/build-config/valid-config/stencil.conf.js new file mode 100644 index 00000000..eb0d8bbf --- /dev/null +++ b/test/_mocks/build-config/valid-config/stencil.conf.js @@ -0,0 +1,52 @@ +/** + * Watch options for the core watcher + * @type {{files: string[], ignored: string[]}} + */ +var watchOptions = { + // If files in these directories change, reload the page. + files: [ + '/templates', + '/lang', + ], + + //Do not watch files in these directories + ignored: [ + '/assets/scss', + '/assets/less', + '/assets/css', + '/assets/dist', + ] +}; + +/** + * Watch any custom files and trigger a rebuild + */ +function development() { + // Rebuild the bundle once at bootup + setTimeout(() => process.send('reload'), 10); +} + +/** + * Hook into the `stencil bundle` command and build your files before they are packaged as a .zip + */ +function production() { + // Rebuild the bundle once at bootup + setTimeout(() => process.send('done'), 10); +} + +if (process.send) { + // running as a forked worker + process.on('message', message => { + if (message === 'development') { + development(); + } + + if (message === 'production') { + production(); + } + }); + + process.send('ready'); +} + +module.exports = { watchOptions }; From e31ef3740d01d068d0a05d1b369f0e3e5cc6b999 Mon Sep 17 00:00:00 2001 From: Mario Campa Date: Wed, 15 Mar 2017 13:17:55 -0700 Subject: [PATCH 2/4] STENCIL-3243 fix a backwards compatible bug + tests --- bin/stencil-start | 2 +- lib/stencil-build-config.js | 4 +-- lib/stencil-build-config.spec.js | 56 +++++++++++++++++++++----------- 3 files changed, 40 insertions(+), 22 deletions(-) diff --git a/bin/stencil-start b/bin/stencil-start index 38a2d424..4b2da2c8 100755 --- a/bin/stencil-start +++ b/bin/stencil-start @@ -297,7 +297,7 @@ function startServer() { }); if (buildConfig.development) { - buildConfig.development(() => Bs.reload()); + buildConfig.development(Bs); } } diff --git a/lib/stencil-build-config.js b/lib/stencil-build-config.js index 94bd43bf..c1d44046 100644 --- a/lib/stencil-build-config.js +++ b/lib/stencil-build-config.js @@ -46,7 +46,7 @@ function onWorkerReady(onReady) { onReadyCallbacks.push(onReady); } -function devWorker(reload) { +function devWorker(browserSync) { if (!worker) { return; } @@ -55,7 +55,7 @@ function devWorker(reload) { worker.send('development'); worker.on('message', message => { if (message === 'reload') { - reload(); + browserSync.reload(); } }); } diff --git a/lib/stencil-build-config.spec.js b/lib/stencil-build-config.spec.js index 6bfa8d39..81aa4255 100644 --- a/lib/stencil-build-config.spec.js +++ b/lib/stencil-build-config.spec.js @@ -41,33 +41,51 @@ describe('stencilBuildConfig', () => { done(); }); - it('should call "done()" function when production bundle finishes', done => { - const buildConfig = loadModule('valid-config'); + describe('production method', () => { + it('should call "done()" function when production bundle finishes', done => { + const buildConfig = loadModule('valid-config'); - expect(buildConfig.production).to.be.a.function(); - buildConfig.production(message => { - expect(message).to.be.undefined(); - done(); + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.be.undefined(); + done(); + }); + }); + + it('should call "done()" function when production bundle finishes (legacy-config)', done => { + const buildConfig = loadModule('legacy-config'); + + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.be.undefined(); + done(); + }); }); - }); - it('should call "done()" function when production bundle finishes (legacy-config)', done => { - const buildConfig = loadModule('legacy-config'); + it('should call done with "noworker" meesage', done => { + const buildConfig = loadModule('noworker-config'); - expect(buildConfig.production).to.be.a.function(); - buildConfig.production(message => { - expect(message).to.be.undefined(); - done(); + expect(buildConfig.production).to.be.a.function(); + buildConfig.production(message => { + expect(message).to.equal('noworker'); + done(); + }); }); }); - it('should call done with "noworker" meesage', done => { - const buildConfig = loadModule('noworker-config'); + describe('development method', () => { + it('should reload the browser when a message "reload" is received from stencil.conf.js', done => { + const buildConfig = loadModule('valid-config'); + + expect(buildConfig.development).to.be.a.function(); + buildConfig.development({ reload: done }); + }); + + it('should reload the browser when "reload" method is called from stencil.conf.js (legacy-config)', done => { + const buildConfig = loadModule('legacy-config'); - expect(buildConfig.production).to.be.a.function(); - buildConfig.production(message => { - expect(message).to.equal('noworker'); - done(); + expect(buildConfig.development).to.be.a.function(); + buildConfig.development({ reload: done }); }); }); }); From 2b73d286f4630b028131a05ae26b4a10246caabd Mon Sep 17 00:00:00 2001 From: Mario Campa Date: Thu, 16 Mar 2017 15:21:50 -0700 Subject: [PATCH 3/4] STENCIL-3243 adding babel-eslint --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 07de75e2..be852ee4 100644 --- a/package.json +++ b/package.json @@ -34,6 +34,7 @@ "accept-language-parser": "^1.0.2", "archiver": "^0.14.4", "async": "^1.3.0", + "babel-eslint": "^7.1.1", "boom": "^2.7.0", "browser-sync": "^2.6.4", "cheerio": "^0.19.0", From e21e79ee984f9f81d1eef637871fe5902b397833 Mon Sep 17 00:00:00 2001 From: Mario Campa Date: Mon, 20 Mar 2017 12:46:51 -0700 Subject: [PATCH 4/4] STENCIL-3243 Renaming stencil-build-config to build-config --- bin/stencil-start | 2 +- lib/{stencil-build-config.js => build-config.js} | 0 lib/{stencil-build-config.spec.js => build-config.spec.js} | 4 ++-- lib/stencil-bundle.js | 2 +- test/_mocks/build-config/noready-config/stencil.conf.js | 2 -- 5 files changed, 4 insertions(+), 6 deletions(-) rename lib/{stencil-build-config.js => build-config.js} (100%) rename lib/{stencil-build-config.spec.js => build-config.spec.js} (95%) diff --git a/bin/stencil-start b/bin/stencil-start index 4b2da2c8..6bfdb318 100755 --- a/bin/stencil-start +++ b/bin/stencil-start @@ -13,7 +13,7 @@ var Pkg = require('../package.json'); var Program = require('commander'); var Server = require('../server'); var ThemeConfig = require('../lib/theme-config'); -var buildConfig = require('../lib/stencil-build-config'); +var buildConfig = require('../lib/build-config'); var stencilToken = require('../server/lib/stencil-token'); var Url = require('url'); var Wreck = require('wreck'); diff --git a/lib/stencil-build-config.js b/lib/build-config.js similarity index 100% rename from lib/stencil-build-config.js rename to lib/build-config.js diff --git a/lib/stencil-build-config.spec.js b/lib/build-config.spec.js similarity index 95% rename from lib/stencil-build-config.spec.js rename to lib/build-config.spec.js index 81aa4255..f7747dca 100644 --- a/lib/stencil-build-config.spec.js +++ b/lib/build-config.spec.js @@ -15,10 +15,10 @@ describe('stencilBuildConfig', () => { function loadModule(mockName) { const path = `${cwd}/test/_mocks/build-config/${mockName}`; - delete require.cache[require.resolve('./stencil-build-config')]; + delete require.cache[require.resolve('./build-config')]; sandbox.stub(process, 'cwd').returns(path); - return require('./stencil-build-config'); + return require('./build-config'); } lab.beforeEach(done => { diff --git a/lib/stencil-bundle.js b/lib/stencil-bundle.js index 2e47532f..5e6e575e 100644 --- a/lib/stencil-bundle.js +++ b/lib/stencil-bundle.js @@ -10,7 +10,7 @@ var Crypto = require('crypto'); var Fs = require('fs'); var Jspm = require('jspm'); var Path = require('path'); -var buildConfig = require('../lib/stencil-build-config'); +var buildConfig = require('../lib/build-config'); var BundleValidator = require('./bundle-validator'); var Cycles = require('./cycles'); var CssAssembler = require('./css-assembler'); diff --git a/test/_mocks/build-config/noready-config/stencil.conf.js b/test/_mocks/build-config/noready-config/stencil.conf.js index aece7f93..32b5923f 100644 --- a/test/_mocks/build-config/noready-config/stencil.conf.js +++ b/test/_mocks/build-config/noready-config/stencil.conf.js @@ -45,8 +45,6 @@ if (process.send) { production(); } }); - - // process.send('ready'); } module.exports = { watchOptions };