Skip to content

Commit

Permalink
fix: Make license information for 3rd party modules deterministic
Browse files Browse the repository at this point in the history
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
  • Loading branch information
susnux committed Aug 1, 2023
1 parent 4e7e5f5 commit 5590061
Show file tree
Hide file tree
Showing 3 changed files with 48 additions and 21 deletions.
4 changes: 0 additions & 4 deletions banner-template.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
@name <%= pkg.name %>
@license <%= pkg.license %>
@version <%= pkg.version %> (generated <%= moment().format('YYYY-MM-DD') %>)

Included dependencies:<% dependencies.sort((a,b) => a.name.localeCompare(b.name)) %>
<% _.forEach(dependencies.sort(), function (dependency) { %>
<%= dependency.name %>
Expand Down
19 changes: 17 additions & 2 deletions lib/appConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const appName = process.env.npm_package_name
export const appVersion = process.env.npm_package_version
export const appNameSanitized = appName.replace(/[/\\]/, '-')

export interface AppOptions extends Omit<BaseOptions, 'nodePolyfills'> {
export interface AppOptions extends BaseOptions {
/**
* Whether to empty the output directory (`js/`)
* @default true
Expand All @@ -31,6 +31,14 @@ export interface AppOptions extends Omit<BaseOptions, 'nodePolyfills'> {
* @default {protocolImports: true}
*/
nodePolyfills?: boolean | NodePolyfillsOptions

/**
* Location of license summary file of third party dependencies
* Pass `false` to disable generating a license file.
*
* @default 'js/vendor.LICENSE.txt'
*/
thirdPartyLicense?: false | string
}

/**
Expand All @@ -47,7 +55,14 @@ export interface AppOptions extends Omit<BaseOptions, 'nodePolyfills'> {
*/
export const createAppConfig = (entries: { [entryAlias: string]: string }, options: AppOptions = {}): UserConfigFn => {
// Add default options
options = { config: {}, nodePolyfills: { protocolImports: true }, ...options }
options = {
config: {},
nodePolyfills: {
protocolImports: true,
},
thirdPartyLicense: options.thirdPartyLicense === undefined ? 'js/vendor.LICENSE.txt' : options.thirdPartyLicense,
...options,
}

return createBaseConfig({
...options,
Expand Down
46 changes: 31 additions & 15 deletions lib/baseConfig.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,13 @@ export interface BaseOptions {
* By default disabled as Nextcloud core already includes the `core-js/stable` polyfills globally
*/
coreJS?: CoreJSPluginOptions
/**
* Location of license summary file of third party dependencies
* Pass `false` to disable generating a license file.
*
* @default 'dist/vendor.LICENSE.txt'
*/
thirdPartyLicense?: false | string
/**
* Vite config to override or extend the base config
*/
Expand All @@ -66,28 +73,47 @@ export function createBaseConfig(options: BaseOptions = {}): UserConfigFn {
const userConfig = await Promise.resolve(typeof options.config === 'function' ? options.config(env) : options.config)

const plugins = []
if (options?.inlineCSS !== false) {
// Inject all imported styles into the javascript bundle
if (options?.inlineCSS !== false) {
plugins.push(injectCSSPlugin())
}
if (options?.nodePolyfills) {

// Add polyfills for node packages
if (options?.nodePolyfills) {
plugins.push(nodePolyfills(typeof options.nodePolyfills === 'object' ? options.nodePolyfills : {}))
}
if (Object.keys(options.replace).length > 0) {

// Replace global variables, built-in `define` option does not work (replaces also strings in 'node_modules/`)
if (Object.keys(options.replace).length > 0) {
plugins.push(replace({
preventAssignment: true,
delimiters: ['\\b', '\\b'],
include: ['src/**/*', 'lib/**/*', 'node_modules/@nextcloud/vue/**/*'],
values: options.replace,
}))
}
if (options.coreJS !== undefined) {

// Add required polyfills, by default browserslist config is used
if (options.coreJS !== undefined) {
plugins.push(corejsPlugin(options.coreJS))
}

// Add license header with all dependencies
if (options.thirdPartyLicense !== false) {
const licenseTemplate = readFileSync(new URL('../banner-template.txt', import.meta.url), 'utf-8')

plugins.push(license({
thirdParty: {
output: {
file: options.thirdPartyLicense || 'dist/vendor.LICENSE.txt',
template: licenseTemplate,
},
},
}))
// Enforce the license is generated at the end so all dependencies are included
plugins.at(-1).enforce = 'post'
}

return mergeConfig(defineConfig({
plugins: [
// Fix build in watch mode with commonjs files
Expand All @@ -108,17 +134,6 @@ export function createBaseConfig(options: BaseOptions = {}): UserConfigFn {
...plugins,
// Remove unneeded whitespace
options?.minify ? minifyPlugin() : undefined,
// Add license header with all dependencies
license({
sourcemap: true,
banner: {
commentStyle: 'regular',
content: () => {
const template = new URL('../banner-template.txt', import.meta.url)
return readFileSync(template, 'utf-8')
},
},
}),
],
define: {
// process env replacement (keep order of this rules)
Expand All @@ -132,6 +147,7 @@ export function createBaseConfig(options: BaseOptions = {}): UserConfigFn {
esbuild: {
legalComments: 'inline',
target: browserslistToEsbuild(),
banner: options.thirdPartyLicense ? `/*! third party licenses: ${options.thirdPartyLicense} */` : undefined,
},
build: {
cssTarget: browserslistToEsbuild(),
Expand Down

0 comments on commit 5590061

Please sign in to comment.