Skip to content

Commit

Permalink
fix(preamble): restore preamble functionality (#3085)
Browse files Browse the repository at this point in the history
Restore the addition of a preamble, specified in stencil.config.ts to all emitted JS files
  - Generate preamble for the following targets:
    - dist-custom-elements-bundle
    - dist-custom-elements
    - dist-hydrate-script
    - www
  - the preamble is not added to:
    - polyfills,
    - non-JS files (d.ts, .json, etc.)
    - the worker file generated by Workbox

Removes legacy (internal) configuration for adding a suffix/prefix/banner to the preamble. 

The BANNER global constant is no longer used and was not exported for consumers, remove it
  • Loading branch information
rwaskiewicz committed Sep 29, 2021
1 parent 6987e43 commit 39caa8c
Show file tree
Hide file tree
Showing 15 changed files with 104 additions and 53 deletions.
4 changes: 2 additions & 2 deletions src/compiler/app-core/app-es5-disabled.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type * as d from '../../declarations';
import { escapeHtml } from '@utils';
import { escapeHtml, generatePreamble } from '@utils';
import { join } from 'path';

export const generateEs5DisabledMessage = async (
Expand Down Expand Up @@ -112,7 +112,7 @@ h2 {
)}</code>
</pre>
`;
return `
return `${generatePreamble(config)}
(function() {
function checkSupport() {
if (!document.body) {
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/bundle/dev-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { basename, dirname, join, relative } from 'path';
import { BuildContext } from '../build/build-ctx';
import { getRollupOptions } from './bundle-output';
import { OutputOptions, PartialResolvedId, rollup } from 'rollup';
import { generatePreamble } from '@utils';

export const devNodeModuleResolveId = async (
config: d.Config,
Expand Down Expand Up @@ -143,6 +144,7 @@ const bundleDevModule = async (
const rollupBuild = await rollup(inputOpts);

const outputOpts: OutputOptions = {
banner: generatePreamble(config),
format: 'es',
};

Expand Down
6 changes: 3 additions & 3 deletions src/compiler/bundle/worker-plugin.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type * as d from '../../declarations';
import type { Plugin, TransformResult, PluginContext } from 'rollup';
import { bundleOutput } from './bundle-output';
import { normalizeFsPath, hasError } from '@utils';
import { normalizeFsPath, hasError, generatePreamble } from '@utils';
import { optimizeModule } from '../optimize/optimize-module';
import { STENCIL_INTERNAL_ID } from './entry-alias-ids';

Expand Down Expand Up @@ -178,10 +178,10 @@ const buildWorker = async (
});

if (build) {
// Generate commonjs output so we can intercept exports at runtme
// Generate commonjs output so we can intercept exports at runtime
const output = await build.generate({
format: 'commonjs',
banner: '(()=>{\n',
banner: `${generatePreamble(config)}\n(()=>{\n`,
footer: '})();',
intro: getWorkerIntro(workerMsgId, config.devMode),
esModule: false,
Expand Down
7 changes: 5 additions & 2 deletions src/compiler/output-targets/dist-collection/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type * as d from '../../../declarations';
import { catchError } from '@utils';
import { catchError, generatePreamble } from '@utils';
import { isOutputTargetDistCollection } from '../output-utils';
import { join, relative } from 'path';
import { writeCollectionManifests } from '../output-collection';
Expand All @@ -19,7 +19,10 @@ export const outputCollection = async (
try {
await Promise.all(
changedModuleFiles.map(async (mod) => {
const code = mod.staticSourceFileText;
let code = mod.staticSourceFileText;
if (config.preamble) {
code = `${generatePreamble(config)}\n${code}`;
}

await Promise.all(
outputTargets.map(async (o) => {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
import type * as d from '../../../declarations';
import type { BundleOptions } from '../../bundle/bundle-interface';
import { bundleOutput } from '../../bundle/bundle-output';
import { catchError, dashToPascalCase, formatComponentRuntimeMeta, hasError, stringifyRuntimeData } from '@utils';
import {
catchError,
dashToPascalCase,
formatComponentRuntimeMeta,
generatePreamble,
hasError,
stringifyRuntimeData,
} from '@utils';
import { getCustomElementsBuildConditionals } from './custom-elements-build-conditionals';
import { isOutputTargetDistCustomElementsBundle } from '../output-utils';
import { join } from 'path';
Expand Down Expand Up @@ -59,6 +66,7 @@ const bundleCustomElements = async (
const build = await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
if (build) {
const rollupOutput = await build.generate({
banner: generatePreamble(config),
format: 'esm',
sourcemap: config.sourceMap,
chunkFileNames: outputTarget.externalRuntime || !config.hashFileNames ? '[name].js' : 'p-[hash].js',
Expand Down
3 changes: 2 additions & 1 deletion src/compiler/output-targets/dist-custom-elements/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import type * as d from '../../../declarations';
import type { BundleOptions } from '../../bundle/bundle-interface';
import { bundleOutput } from '../../bundle/bundle-output';
import { catchError, dashToPascalCase, hasError } from '@utils';
import { catchError, dashToPascalCase, generatePreamble, hasError } from '@utils';
import { getCustomElementsBuildConditionals } from '../dist-custom-elements-bundle/custom-elements-build-conditionals';
import { isOutputTargetDistCustomElements } from '../output-utils';
import { join } from 'path';
Expand Down Expand Up @@ -63,6 +63,7 @@ const bundleCustomElements = async (
const build = await bundleOutput(config, compilerCtx, buildCtx, bundleOpts);
if (build) {
const rollupOutput = await build.generate({
banner: generatePreamble(config),
format: 'esm',
sourcemap: config.sourceMap,
chunkFileNames: outputTarget.externalRuntime || !config.hashFileNames ? '[name].js' : 'p-[hash].js',
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import type * as d from '../../../declarations';
import { bundleHydrateFactory } from './bundle-hydrate-factory';
import { catchError, createOnWarnFn, loadRollupDiagnostics } from '@utils';
import { catchError, createOnWarnFn, generatePreamble, loadRollupDiagnostics } from '@utils';
import { getBuildFeatures, updateBuildConditionals } from '../../app-core/app-data';
import { HYDRATE_FACTORY_INTRO, HYDRATE_FACTORY_OUTRO } from './hydrate-factory-closure';
import { updateToHydrateComponents } from './update-to-hydrate-components';
Expand Down Expand Up @@ -57,6 +57,7 @@ export const generateHydrateApp = async (

const rollupAppBuild = await rollup(rollupOptions);
const rollupOutput = await rollupAppBuild.generate({
banner: generatePreamble(config),
format: 'cjs',
file: 'index.js',
});
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/output-targets/dist-lazy/generate-cjs.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { generateLazyModules } from './generate-lazy-module';
import { join } from 'path';
import type { OutputOptions, RollupBuild } from 'rollup';
import { relativeImport } from '../output-utils';
import { generatePreamble } from '@utils';

export const generateCjs = async (
config: d.Config,
Expand All @@ -17,6 +18,7 @@ export const generateCjs = async (
if (cjsOutputs.length > 0) {
const outputTargetType = cjsOutputs[0].type;
const esmOpts: OutputOptions = {
banner: generatePreamble(config),
format: 'cjs',
entryFileNames: '[name].cjs.js',
assetFileNames: '[name]-[hash][extname]',
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type * as d from '../../../declarations';
import { generateRollupOutput } from '../../app-core/bundle-app-core';
import { generateLazyModules } from './generate-lazy-module';
import type { OutputOptions, RollupBuild } from 'rollup';
import { getDynamicImportFunction } from '@utils';
import { generatePreamble, getDynamicImportFunction } from '@utils';

export const generateEsmBrowser = async (
config: d.Config,
Expand All @@ -15,6 +15,7 @@ export const generateEsmBrowser = async (
if (esmOutputs.length) {
const outputTargetType = esmOutputs[0].type;
const esmOpts: OutputOptions = {
banner: generatePreamble(config),
format: 'es',
entryFileNames: '[name].esm.js',
chunkFileNames: config.hashFileNames ? 'p-[hash].js' : '[name]-[hash].js',
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/output-targets/dist-lazy/generate-esm.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { join } from 'path';
import type { OutputOptions, RollupBuild } from 'rollup';
import { relativeImport } from '../output-utils';
import type { RollupResult } from '../../../declarations';
import { generatePreamble } from '@utils';

export const generateEsm = async (
config: d.Config,
Expand All @@ -17,6 +18,7 @@ export const generateEsm = async (
const esmOutputs = outputTargets.filter((o) => !!o.esmDir && !o.isBrowserBuild);
if (esmOutputs.length + esmEs5Outputs.length > 0) {
const esmOpts: OutputOptions = {
banner: generatePreamble(config),
format: 'es',
entryFileNames: '[name].js',
assetFileNames: '[name]-[hash][extname]',
Expand Down
2 changes: 2 additions & 0 deletions src/compiler/output-targets/dist-lazy/generate-system.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import { getAppBrowserCorePolyfills } from '../../app-core/app-polyfills';
import { join } from 'path';
import type { OutputOptions, RollupBuild } from 'rollup';
import { relativeImport } from '../output-utils';
import { generatePreamble } from '@utils';

export const generateSystem = async (
config: d.Config,
Expand All @@ -17,6 +18,7 @@ export const generateSystem = async (

if (systemOutputs.length > 0) {
const esmOpts: OutputOptions = {
banner: generatePreamble(config),
format: 'system',
entryFileNames: config.hashFileNames ? 'p-[hash].system.js' : '[name].system.js',
chunkFileNames: config.hashFileNames ? 'p-[hash].system.js' : '[name]-[hash].system.js',
Expand Down
11 changes: 5 additions & 6 deletions src/compiler/output-targets/output-lazy-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import type * as d from '../../declarations';
import { getClientPolyfill } from '../app-core/app-polyfills';
import { isOutputTargetDistLazyLoader, relativeImport } from './output-utils';
import { join, relative } from 'path';
import { normalizePath } from '@utils';
import { generatePreamble, normalizePath } from '@utils';

export const outputLazyLoader = async (config: d.Config, compilerCtx: d.CompilerCtx) => {
const outputTargets = config.outputTargets.filter(isOutputTargetDistLazyLoader);
Expand Down Expand Up @@ -49,16 +49,16 @@ const generateLoader = async (
const polyfillsEntryPoint = join(es2017Dir, 'polyfills/index.js');
const cjsEntryPoint = join(cjsDir, 'loader.cjs.js');
const polyfillsExport = `export * from '${normalizePath(relative(loaderPath, polyfillsEntryPoint))}';`;
const indexContent = `
const indexContent = `${generatePreamble(config)}
${es5HtmlElement}
${polyfillsExport}
export * from '${normalizePath(relative(loaderPath, es5EntryPoint))}';
`;
const indexES2017Content = `
const indexES2017Content = `${generatePreamble(config)}
${polyfillsExport}
export * from '${normalizePath(relative(loaderPath, es2017EntryPoint))}';
`;
const indexCjsContent = `
const indexCjsContent = `${generatePreamble(config)}
module.exports = require('${normalizePath(relative(loaderPath, cjsEntryPoint))}');
module.exports.applyPolyfills = function() { return Promise.resolve() };
`;
Expand All @@ -75,8 +75,7 @@ module.exports.applyPolyfills = function() { return Promise.resolve() };
};

const generateIndexDts = (indexDtsPath: string, componentsDtsPath: string) => {
return `
export * from '${relativeImport(indexDtsPath, componentsDtsPath, '.d.ts')}';
return `export * from '${relativeImport(indexDtsPath, componentsDtsPath, '.d.ts')}';
export interface CustomElementsDefineOptions {
exclude?: string[];
resourcesUrl?: string;
Expand Down
1 change: 0 additions & 1 deletion src/utils/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,5 +87,4 @@ export const XML_NS = 'http://www.w3.org/XML/1998/namespace';
/**
* File names and value
*/
export const BANNER = `Built with http://stenciljs.com`;
export const COLLECTION_MANIFEST_FILE_NAME = 'collection-manifest.json';
52 changes: 52 additions & 0 deletions src/utils/test/util.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,58 @@
import { mockConfig } from '@stencil/core/testing';
import * as util from '../util';

describe('util', () => {
describe('generatePreamble', () => {
it('generates a comment with a single line preamble', () => {
const testConfig = mockConfig();
testConfig.preamble = 'I am Stencil';

const result = util.generatePreamble(testConfig);

expect(result).toBe(`/*!
* I am Stencil
*/`);
});

it('generates a comment with a multi-line preamble', () => {
const testConfig = mockConfig();
testConfig.preamble = 'I am Stencil\nHear me roar';

const result = util.generatePreamble(testConfig);

expect(result).toBe(`/*!
* I am Stencil
* Hear me roar
*/`);
});

it('returns an empty string if no preamble is provided', () => {
const testConfig = mockConfig();

const result = util.generatePreamble(testConfig);

expect(result).toBe('');
});

it('returns an empty string a null preamble is provided', () => {
const testConfig = mockConfig();
testConfig.preamble = null;

const result = util.generatePreamble(testConfig);

expect(result).toBe('');
});

it('returns an empty string if an empty preamble is provided', () => {
const testConfig = mockConfig();
testConfig.preamble = '';

const result = util.generatePreamble(testConfig);

expect(result).toBe('');
});
});

describe('isTsFile', () => {
it('should return true for regular .ts and .tsx files', () => {
expect(util.isTsFile('.ts')).toEqual(true);
Expand Down
49 changes: 14 additions & 35 deletions src/utils/util.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type * as d from '../declarations';
import { BANNER } from './constants';
import { buildError } from './message-utils';
import { dashToPascalCase, isString, toDashCase } from './helpers';

Expand Down Expand Up @@ -88,45 +87,25 @@ export const isHtmlFile = (filePath: string) => {
return hasFileExtension(filePath, ['html', 'htm']);
};

export const generatePreamble = (
config: d.Config,
opts: { prefix?: string; suffix?: string; defaultBanner?: boolean } = {}
) => {
let preamble: string[] = [];

if (config.preamble) {
preamble = config.preamble.split('\n');
}

if (typeof opts.prefix === 'string') {
opts.prefix.split('\n').forEach((c) => {
preamble.push(c);
});
}

if (opts.defaultBanner === true) {
preamble.push(BANNER);
}
/**
* Generate the preamble to be placed atop the main file of the build
* @param config the Stencil configuration file
* @return the generated preamble
*/
export const generatePreamble = (config: d.Config): string => {
const { preamble } = config;

if (typeof opts.suffix === 'string') {
opts.suffix.split('\n').forEach((c) => {
preamble.push(c);
});
if (!preamble) {
return '';
}

if (preamble.length > 1) {
preamble = preamble.map((l) => ` * ${l}`);
// generate the body of the JSDoc-style comment
const preambleComment: string[] = preamble.split('\n').map((l) => ` * ${l}`);

preamble.unshift(`/*!`);
preamble.push(` */`);
preambleComment.unshift(`/*!`);
preambleComment.push(` */`);

return preamble.join('\n');
}

if (opts.defaultBanner === true) {
return `/*! ${BANNER} */`;
}
return '';
return preambleComment.join('\n');
};

const lineBreakRegex = /\r?\n|\r/g;
Expand Down

0 comments on commit 39caa8c

Please sign in to comment.