diff --git a/CHANGELOG.md b/CHANGELOG.md index 99f5bb3..1363d27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,30 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html). +## [4.0.0-beta.1] - 2020-10-15 + +### Fixed +- Typescript type declarations don't conflict anymore (Vue 3) +- Fixed treeshaking issues (Vue 2) + - package.json includes `"sideEffects": false` + - Marked appropriate functions as `/*#__PURE__*/` + - Upstream issues may still exist in [vue-runtime-helpers](https://github.com/znck/vue-runtime-helpers/pull/5), but current testing shows output should still be shakeable + +### Changed/Removed +- Update template dependencies + - @babel/core 7.12.0 + - @babel/preset-env 7.12.0 + - @babel/preset-typescript 7.12.0 + - @rollup/plugin-babel 5.2.1 + - @vue/cli-plugin-babel 4.5.7 + - @vue/cli-plugin-typescript 4.5.7 + - @vue/cli-service 4.5.7 + - @vue/compiler-sfc 3.0.0 + - rollup 2.30.0 + - rollup-plugin-postcss 3.1.8 + - rollup-plugin-terser 7.0.2 + - vue 3.0.0 (Vue 3) + ## [4.0.0-beta.0] - 2020-09-04 ### Added diff --git a/package-lock.json b/package-lock.json index 47f81ba..5eee30d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "vue-sfc-rollup", - "version": "4.0.0-beta.0", + "version": "4.0.0-beta.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index f18d732..73bcd09 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "description": "Quickly generate redistributable components with Rollup", "author": "Michael Dodge", "license": "ISC", - "version": "4.0.0-beta.0", + "version": "4.0.0-beta.1", "bin": { "sfc-init": "./sfc-init.js" }, diff --git a/templates/library/library-package.json b/templates/library/library-package.json index b8d89d0..2ae8f40 100644 --- a/templates/library/library-package.json +++ b/templates/library/library-package.json @@ -18,6 +18,7 @@ <% } -%> "src/**/*.vue" ], + "sideEffects": false, "scripts": { "serve": "vue-cli-service serve dev/serve.<% if (ts) { %>ts<% } else { %>js<% } %>", @@ -31,31 +32,31 @@ }, "devDependencies": { - "@babel/core": "^7.11.4", - "@babel/preset-env": "^7.11.0", + "@babel/core": "^7.12.0", + "@babel/preset-env": "^7.12.0", <% if (ts) { -%> - "@babel/preset-typescript": "^7.10.4", + "@babel/preset-typescript": "^7.12.0", <% } -%> "@rollup/plugin-alias": "^3.1.1", - "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-babel": "^5.2.1", "@rollup/plugin-commonjs": "^14.0.0", "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-replace": "^2.3.3", - "@vue/cli-plugin-babel": "^4.5.4", + "@vue/cli-plugin-babel": "^4.5.7", <% if (ts) { -%> - "@vue/cli-plugin-typescript": "^4.5.4", + "@vue/cli-plugin-typescript": "^4.5.7", <% } -%> - "@vue/cli-service": "^4.5.4", + "@vue/cli-service": "^4.5.7", <% if (version === 3) { -%> - "@vue/compiler-sfc": "^3.0.0-rc.9", + "@vue/compiler-sfc": "^3.0.0", <% } -%> "cross-env": "^7.0.2", "minimist": "^1.2.5", - "rollup": "^2.26.5", + "rollup": "^2.30.0", <% if (version === 3) { -%> - "rollup-plugin-postcss": "^3.1.6", + "rollup-plugin-postcss": "^3.1.8", <% } -%> - "rollup-plugin-terser": "^7.0.0", + "rollup-plugin-terser": "^7.0.2", <% if (version === 3) { -%> "rollup-plugin-vue": "^6.0.0-beta.10", <% } else { -%> @@ -65,7 +66,7 @@ "typescript": "^3.8.3", <% } -%> <% if (version === 3) { -%> - "vue": "^3.0.0-rc.9" + "vue": "^3.0.0" <% } else { -%> "vue": "^2.6.12", "vue-template-compiler": "^2.6.12" @@ -73,7 +74,7 @@ }, "peerDependencies": { <% if (version === 3) { -%> - "vue": "^3.0.0-rc.9" + "vue": "^3.0.0" <% } else { -%> "vue": "^2.6.12" <% } -%> diff --git a/templates/library/library.d.ts b/templates/library/library.d.ts index 04b93ba..0f7ad03 100644 --- a/templates/library/library.d.ts +++ b/templates/library/library.d.ts @@ -1,12 +1,12 @@ <% if (version === 3) { -%> -import { defineComponent, Plugin } from 'vue'; +import { DefineComponent, Plugin } from 'vue'; <% } else { -%> import Vue, { PluginFunction, VueConstructor } from 'vue'; <% } -%> -declare const <%-componentNamePascal%>: { install: <% if (version === 3) { %>Plugin['install']<% } else { %>PluginFunction<% } %> }; +declare const <%-componentNamePascal%>: <% if (version === 3) { %>Exclude<% } else { %>PluginFunction<% } %>; export default <%-componentNamePascal%>; -export const <%-componentNamePascal%>Sample: <% if (version === 3) { %>ReturnType<% } else { %>VueConstructor<% } %>; +export const <%-componentNamePascal%>Sample: <% if (version === 3) { %>DefineComponent<% } else { %>VueConstructor<% } %>; diff --git a/templates/library/shims-vue.d.ts b/templates/library/shims-vue.d.ts index cc650a8..92867db 100644 --- a/templates/library/shims-vue.d.ts +++ b/templates/library/shims-vue.d.ts @@ -1,11 +1,11 @@ declare module '*.vue' { <% if (version === 3) { -%> - import { defineComponent } from 'vue'; + import { DefineComponent } from 'vue'; - const Component: ReturnType + const Component: DefineComponent; export default Component; <% } else { -%> import Vue from 'vue'; - export default Vue + export default Vue; <% } -%> } diff --git a/templates/library/src/entry.esm.ts b/templates/library/src/entry.esm.ts index 9eba129..d02cfb7 100644 --- a/templates/library/src/entry.esm.ts +++ b/templates/library/src/entry.esm.ts @@ -1,18 +1,17 @@ <% if (ts) { if (version === 3) { -%> import { App, Plugin } from 'vue'; - <% } else { -%> -import _Vue, { PluginFunction, PluginObject } from 'vue'; - +import _Vue, { PluginFunction } from 'vue'; <% } } -%> + // Import vue components import * as components from '@/lib-components/index'; // install function executed by Vue.use() <% if (ts) { -%> -const install: <% if (version === 3) { %>Plugin['install']<% } else { %>PluginFunction<% } %> = function install<%-componentNamePascal%>(<% if (version === 3) { %>app: App<% } else { %>Vue: typeof _Vue<% } %>) { +const install: <% if (version === 3) { %>Exclude<% } else { %>PluginFunction<% } %> = function install<%-componentNamePascal%>(<% if (version === 3) { %>app: App<% } else { %>Vue: typeof _Vue<% } %>) { <% } else { -%> const install = function install<%-componentNamePascal%>(<% if (version === 3) { %>app<% } else { %>Vue<% } %>) { <% } -%> @@ -22,9 +21,7 @@ const install = function install<%-componentNamePascal%>(<% if (version === 3) { }; // Create module definition for Vue.use() -export default { - install, -}<% if (ts) { %> as <% if (version === 3) { %>Plugin<% } else { %>PluginObject<% } } %>; +export default install; // To allow individual component use, export components // each can be registered via Vue.component() diff --git a/templates/library/src/entry.ts b/templates/library/src/entry.ts index 680360b..fc8b45c 100644 --- a/templates/library/src/entry.ts +++ b/templates/library/src/entry.ts @@ -1,23 +1,23 @@ -<% if (ts && version === 3) { -%> -import { defineComponent, Plugin } from 'vue'; - -<% } -%> // iife/cjs usage extends esm default export - so import it all -// import * as components from '@/lib-components/index'; import plugin, * as components from '@/entry.esm'; -// Attach named exports directly to component. IIFE/CJS will -// only expose one global var, with named exports exposed as properties of -// that global var (eg. VivintIcon.iconList) -<% if (ts && version === 3) { -%> -type PluginObject = Plugin & { [key: string]: ReturnType; }; +// Attach named exports directly to plugin. IIFE/CJS will +// only expose one global var, with component exports exposed as properties of +// that global var (eg. plugin.component) +<% if (ts) { -%> +type NamedExports = Exclude; +type ExtendedPlugin = typeof plugin & NamedExports; <% } -%> Object.entries(components).forEach(([componentName, component]) => { -<% if (ts && version === 3) { -%> - if (componentName !== 'default') (plugin as PluginObject)[componentName] = component as any as ReturnType; + if (componentName !== 'default') { +<% if (ts) { -%> + const key = componentName as Exclude; + const val = component as Exclude; + (plugin as ExtendedPlugin)[key] = val; <% } else { -%> - if (componentName !== 'default') plugin[componentName] = component; + plugin[componentName] = component; <% } -%> + } }); export default plugin; diff --git a/templates/library/src/lib-components/component.vue b/templates/library/src/lib-components/component.vue index 4e50510..8bd9af9 100644 --- a/templates/library/src/lib-components/component.vue +++ b/templates/library/src/lib-components/component.vue @@ -17,7 +17,7 @@ interface SampleData { } <% } -%> -export default <% if (version === 3) {%>defineComponent(<% } else if (ts) { %>Vue.extend(<% } %>{ +export default /*#__PURE__*/<% if (version === 3) {%>defineComponent(<% } else if (ts) { %>Vue.extend(<% } %>{ name: '<%-componentNamePascal%>Sample', // vue component name data()<% if (ts) { %>: SampleData<% } %> { return { diff --git a/templates/single/shims-vue.d.ts b/templates/single/shims-vue.d.ts index cc650a8..92867db 100644 --- a/templates/single/shims-vue.d.ts +++ b/templates/single/shims-vue.d.ts @@ -1,11 +1,11 @@ declare module '*.vue' { <% if (version === 3) { -%> - import { defineComponent } from 'vue'; + import { DefineComponent } from 'vue'; - const Component: ReturnType + const Component: DefineComponent; export default Component; <% } else { -%> import Vue from 'vue'; - export default Vue + export default Vue; <% } -%> } diff --git a/templates/single/single-component.d.ts b/templates/single/single-component.d.ts index ed475f2..ee09f33 100644 --- a/templates/single/single-component.d.ts +++ b/templates/single/single-component.d.ts @@ -1,14 +1,8 @@ <% if (version === 3) { -%> -import { defineComponent, Plugin } from 'vue'; - -type InstallableComponent = ReturnType & { install: Plugin['install'] }; +import { DefineComponent, Plugin } from 'vue'; <% } else { -%> import Vue, { PluginFunction, VueConstructor } from 'vue'; - -export interface InstallableComponent extends VueConstructor { - install: PluginFunction; -} <% } -%> -declare const <%-componentNamePascal%>: InstallableComponent; +declare const <%-componentNamePascal%>: <% if (version === 3) { %>DefineComponent & { install: Exclude }<% } else { %>VueConstructor & { install: PluginFunction; }<% } %>; export default <%-componentNamePascal%>; diff --git a/templates/single/single-package.json b/templates/single/single-package.json index b8d89d0..2ae8f40 100644 --- a/templates/single/single-package.json +++ b/templates/single/single-package.json @@ -18,6 +18,7 @@ <% } -%> "src/**/*.vue" ], + "sideEffects": false, "scripts": { "serve": "vue-cli-service serve dev/serve.<% if (ts) { %>ts<% } else { %>js<% } %>", @@ -31,31 +32,31 @@ }, "devDependencies": { - "@babel/core": "^7.11.4", - "@babel/preset-env": "^7.11.0", + "@babel/core": "^7.12.0", + "@babel/preset-env": "^7.12.0", <% if (ts) { -%> - "@babel/preset-typescript": "^7.10.4", + "@babel/preset-typescript": "^7.12.0", <% } -%> "@rollup/plugin-alias": "^3.1.1", - "@rollup/plugin-babel": "^5.2.0", + "@rollup/plugin-babel": "^5.2.1", "@rollup/plugin-commonjs": "^14.0.0", "@rollup/plugin-node-resolve": "^9.0.0", "@rollup/plugin-replace": "^2.3.3", - "@vue/cli-plugin-babel": "^4.5.4", + "@vue/cli-plugin-babel": "^4.5.7", <% if (ts) { -%> - "@vue/cli-plugin-typescript": "^4.5.4", + "@vue/cli-plugin-typescript": "^4.5.7", <% } -%> - "@vue/cli-service": "^4.5.4", + "@vue/cli-service": "^4.5.7", <% if (version === 3) { -%> - "@vue/compiler-sfc": "^3.0.0-rc.9", + "@vue/compiler-sfc": "^3.0.0", <% } -%> "cross-env": "^7.0.2", "minimist": "^1.2.5", - "rollup": "^2.26.5", + "rollup": "^2.30.0", <% if (version === 3) { -%> - "rollup-plugin-postcss": "^3.1.6", + "rollup-plugin-postcss": "^3.1.8", <% } -%> - "rollup-plugin-terser": "^7.0.0", + "rollup-plugin-terser": "^7.0.2", <% if (version === 3) { -%> "rollup-plugin-vue": "^6.0.0-beta.10", <% } else { -%> @@ -65,7 +66,7 @@ "typescript": "^3.8.3", <% } -%> <% if (version === 3) { -%> - "vue": "^3.0.0-rc.9" + "vue": "^3.0.0" <% } else { -%> "vue": "^2.6.12", "vue-template-compiler": "^2.6.12" @@ -73,7 +74,7 @@ }, "peerDependencies": { <% if (version === 3) { -%> - "vue": "^3.0.0-rc.9" + "vue": "^3.0.0" <% } else { -%> "vue": "^2.6.12" <% } -%> diff --git a/templates/single/src/component.vue b/templates/single/src/component.vue index f37b993..31765c6 100644 --- a/templates/single/src/component.vue +++ b/templates/single/src/component.vue @@ -17,7 +17,7 @@ interface SampleData { } <% } -%> -export default <% if (version === 3) {%>defineComponent(<% } else if (ts) { %>Vue.extend(<% } %>{ +export default /*#__PURE__*/<% if (version === 3) {%>defineComponent(<% } else if (ts) { %>Vue.extend(<% } %>{ name: '<%-componentNamePascal%>', // vue component name data()<% if (ts) { %>: SampleData<% } %> { return { diff --git a/templates/single/src/entry.esm.ts b/templates/single/src/entry.esm.ts index 74bddf1..43c2efe 100644 --- a/templates/single/src/entry.esm.ts +++ b/templates/single/src/entry.esm.ts @@ -1,46 +1,39 @@ <% if (ts && version === 3) { -%> -import { App, defineComponent, Plugin } from 'vue'; - +import { App, DefineComponent, Plugin } from 'vue'; <% } else if (ts && version === 2) { -%> -import _Vue, { PluginFunction, PluginObject, VueConstructor } from 'vue'; - +import _Vue, { PluginObject, VueConstructor } from 'vue'; <% } -%> + // Import vue component import component from '@/<%-componentName%>.vue'; <% if (ts) { -%> // Define typescript interfaces for installable component <% if (version === 3) { -%> -type InstallableComponent = ReturnType & { install: Plugin['install'] }; +type InstallableComponent = DefineComponent & { install: Exclude }; <% } else { -%> type InstallableComponent = VueConstructor<_Vue> & PluginObject; <% } -%> <% } -%> -// install function executed by Vue.use() +// Default export is installable instance of component. +// IIFE injects install function into component, allowing component +// to be registered via Vue.use() as well as Vue.component(), +export default /*#__PURE__*/(()<% if (ts) { %>: InstallableComponent<% } %> => { + <% if (ts) { %>// Assign InstallableComponent type<% } else { %>// Get component instance<% } %> + const installable = component<% if (ts) { %> as unknown as InstallableComponent<% } %>; + + // Attach install function executed by Vue.use() <% if (ts) { -%> -const install: <% if (version === 3) { %>Plugin['install']<% } else { %>PluginFunction<% } %> = function install<%-componentNamePascal%>(<% if (version === 3) { %>app: App<% } else { %>Vue: typeof _Vue<% } %>) { + installable.install = (<% if (version === 3) { %>app: App<% } else { %>Vue: typeof _Vue<% } %>) => { <% } else { -%> -const install = function install<%-componentNamePascal%>(<% if (version === 3) { %>app<% } else { %>Vue<% } %>) { -<% } -%> - <% if (version === 3) { %>app<% } else { %>Vue<% } %>.component('<%-componentNamePascal%>', component); -}; - -// Inject install function into component - allows component -// to be registered via Vue.use() as well as Vue.component() -<% if (ts) { -%> -// eslint-disable-next-line @typescript-eslint/no-explicit-any -(component as any as InstallableComponent).install = install; - -// Export component by default -export default (component as any as InstallableComponent); -<% } else { -%> -component.install = install; - -// Export component by default -export default component; + installable.install = (<% if (version === 3) { %>app<% } else { %>Vue<% } %>) => { <% } -%> + <% if (version === 3) { %>app<% } else { %>Vue<% } %>.component('<%-componentNamePascal%>', installable); + }; + return installable; +})(); // It's possible to expose named exports when writing components that can // also be used as directives, etc. - eg. import { RollupDemoDirective } from 'rollup-demo'; -// export const RollupDemoDirective = component; +// export const RollupDemoDirective = directive; diff --git a/templates/single/src/entry.ts b/templates/single/src/entry.ts index f7b0d1f..f7ac843 100644 --- a/templates/single/src/entry.ts +++ b/templates/single/src/entry.ts @@ -3,9 +3,9 @@ import component, * as namedExports from '@/entry.esm'; // Attach named exports directly to component. IIFE/CJS will // only expose one global var, with named exports exposed as properties of -// that global var (eg. VivintIcon.iconList) +// that global var (eg. plugin.namedExport) Object.entries(namedExports).forEach(([exportName, exported]) => { if (exportName !== 'default') component[exportName] = exported; }); -export default component; +export default component<% if (ts) { %> as typeof component & Exclude<% } %>;