feat(bridge): enable automatic global imports for nuxt2 (#609)

This commit is contained in:
Daniel Roe 2021-10-02 17:59:32 +01:00 committed by GitHub
parent bba79f4836
commit b712de9aa2
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 105 additions and 14 deletions

View File

@ -28,8 +28,8 @@ ESM support | 🌙 Partial | 👍 Better | ✅
Typescript | ☑️ Opt-in | 🚧 Faster | ✅ Typescript | ☑️ Opt-in | 🚧 Faster | ✅
Composition API | ⚠️ Deprecated | ✅ | ✅ Composition API | ⚠️ Deprecated | ✅ | ✅
Components Auto Import | ✅ | ✅ | ✅ Components Auto Import | ✅ | ✅ | ✅
Auto Imports | ❌ | 🚧 | ✅ Auto Imports | ❌ | | ✅
Webpack | 4 | 4 | 5 Webpack | 4 | 4 | 5
Vite | ⚠️ Partial | 🚧 Partial | 🚧 Experimental Vite | ⚠️ Partial | 🚧 Partial | 🚧 Experimental
Nuxi CLI | ❌ Old | ✅ | ✅ Nuxi CLI | ❌ Old | ✅ | ✅

View File

@ -0,0 +1,77 @@
import { installModule, useNuxt } from '@nuxt/kit'
import globalImports from 'nuxt3/src/global-imports/module'
// TODO: implement these: https://github.com/nuxt/framework/issues/549
const disabled = [
'useMeta',
'useAsyncData',
'asyncData'
]
const identifiers = {
'#app': [
'defineNuxtComponent',
'useNuxtApp',
'defineNuxtPlugin',
'useRoute',
'useRouter'
],
'@vue/composition-api': [
// lifecycle
'onActivated',
'onBeforeMount',
'onBeforeUnmount',
'onBeforeUpdate',
'onDeactivated',
'onErrorCaptured',
'onMounted',
'onServerPrefetch',
'onUnmounted',
'onUpdated',
// reactivity,
'computed',
'customRef',
'isReadonly',
'isRef',
'markRaw',
'reactive',
'readonly',
'ref',
'shallowReactive',
'shallowReadonly',
'shallowRef',
'toRaw',
'toRef',
'toRefs',
'triggerRef',
'unref',
'watch',
'watchEffect',
// component
'defineComponent',
'defineAsyncComponent',
'getCurrentInstance',
'h',
'inject',
'nextTick',
'provide',
'useCssModule'
]
}
const defaultIdentifiers = {}
for (const pkg in identifiers) {
for (const id of identifiers[pkg]) {
defaultIdentifiers[id] = pkg
}
}
export async function setupGlobalImports () {
const nuxt = useNuxt()
nuxt.options.globalImports = nuxt.options.globalImports || {}
nuxt.options.globalImports.disabled = nuxt.options.globalImports.disabled || disabled
nuxt.options.globalImports.identifiers = Object.assign({}, defaultIdentifiers, nuxt.options.globalImports.identifiers)
await installModule(nuxt, globalImports)
}

View File

@ -4,6 +4,7 @@ import { setupNitroBridge } from './nitro'
import { setupAppBridge } from './app' import { setupAppBridge } from './app'
import { setupCAPIBridge } from './capi' import { setupCAPIBridge } from './capi'
import { setupBetterResolve } from './resolve' import { setupBetterResolve } from './resolve'
import { setupGlobalImports } from './global-imports'
export default defineNuxtModule({ export default defineNuxtModule({
name: 'nuxt-bridge', name: 'nuxt-bridge',
@ -13,12 +14,15 @@ export default defineNuxtModule({
vite: false, vite: false,
app: {}, app: {},
capi: {}, capi: {},
globalImports: true,
// TODO: Remove from 2.16 // TODO: Remove from 2.16
postcss8: true, postcss8: true,
swc: true, swc: true,
resolve: true resolve: true
}, },
async setup (opts, nuxt) { async setup (opts, nuxt) {
const _require = createRequire(import.meta.url)
if (opts.nitro) { if (opts.nitro) {
await setupNitroBridge() await setupNitroBridge()
} }
@ -31,7 +35,9 @@ export default defineNuxtModule({
} }
await setupCAPIBridge(opts.capi) await setupCAPIBridge(opts.capi)
} }
const _require = createRequire(import.meta.url) if (opts.globalImports) {
await setupGlobalImports()
}
if (opts.vite) { if (opts.vite) {
await installModule(nuxt, _require.resolve('nuxt-vite')) await installModule(nuxt, _require.resolve('nuxt-vite'))
} }

View File

@ -8,7 +8,10 @@ export default defineNuxtModule<GlobalImportsOptions>({
name: 'global-imports', name: 'global-imports',
configKey: 'globalImports', configKey: 'globalImports',
defaults: { identifiers: defaultIdentifiers }, defaults: { identifiers: defaultIdentifiers },
setup ({ identifiers }, nuxt) { setup ({ disabled = [], identifiers }, nuxt) {
for (const key of disabled) {
delete identifiers[key]
}
if (nuxt.options.dev) { if (nuxt.options.dev) {
// Add all imports to globalThis in development mode // Add all imports to globalThis in development mode
addPluginTemplate({ addPluginTemplate({

View File

@ -8,11 +8,11 @@ const excludeRE = [
// defined as function // defined as function
/\bfunction\s*([\s\S]+?)\s*\(/g, /\bfunction\s*([\s\S]+?)\s*\(/g,
// defined as local variable // defined as local variable
/\b(?:const|let|var)\s*([\w\d_$]+?)\b/g /\b(?:const|let|var)\s*(\{([\s\S]*?)\}|[\w\d_$]+?\b)/g
] ]
const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm const multilineCommentsRE = /\/\*(.|[\r\n])*?\*\//gm
const singlelineCommentsRE = /\/\/.*/g const singlelineCommentsRE = /^\s*\/\/.*$/gm
function stripeComments (code: string) { function stripeComments (code: string) {
return code return code
@ -73,10 +73,17 @@ export const TransformPlugin = createUnplugin((map: IdentifierMap) => {
modules[moduleName].push(name) modules[moduleName].push(name)
}) })
// Needed for webpack4/bridge support
const isCJSContext = code.includes('require(')
// stringify import // stringify import
const imports = Object.entries(modules) const imports = !isCJSContext
.map(([moduleName, names]) => `import { ${names.join(',')} } from '${moduleName}';`) ? Object.entries(modules)
.join('') .map(([moduleName, names]) => `import { ${names.join(',')} } from '${moduleName}';`)
.join('')
: Object.entries(modules)
.map(([moduleName, names]) => `const { ${names.join(',')} } = require('${moduleName}');`)
.join('')
return imports + code return imports + code
} }

View File

@ -3,4 +3,5 @@ export type Identifiers = [string, string][]
export interface GlobalImportsOptions { export interface GlobalImportsOptions {
identifiers?: IdentifierMap identifiers?: IdentifierMap
disabled?: string[]
} }

View File

@ -6,7 +6,6 @@
</template> </template>
<script> <script>
import { useRoute } from '#app'
export default { export default {
setup () { setup () {
const route = useRoute() const route = useRoute()

View File

@ -3,8 +3,6 @@
</template> </template>
<script> <script>
import { defineComponent, ref } from '#app'
export default defineComponent({ export default defineComponent({
setup () { setup () {
return { return {

View File

@ -21,7 +21,7 @@
<tr><td><b>onMounted</b></td><td> {{ mounted }}</td></tr> <tr><td><b>onMounted</b></td><td> {{ mounted }}</td></tr>
<!-- Wrappers --> <!-- Wrappers -->
<tr><td><b>useStore</b></td><td> {{ store.state.test }}</td></tr> <tr><td><b>useStore</b></td><td> {{ store.state.test }}</td></tr>
<tr><td><b>useRoute</b></td><td> {{ route.path === '/legacy' ? '✅' : '❌' }}</td></tr> <tr><td><b>useRoute</b></td><td> {{ route.path === '/legacy-capi' ? '✅' : '❌' }}</td></tr>
<tr><td><b>useContext</b></td><td> {{ Object.keys(context).length ? '✅' : '❌' }}</td></tr> <tr><td><b>useContext</b></td><td> {{ Object.keys(context).length ? '✅' : '❌' }}</td></tr>
<!-- Helpers --> <!-- Helpers -->
<tr><td><b>useAsync</b></td><td> {{ async }}</td></tr> <tr><td><b>useAsync</b></td><td> {{ async }}</td></tr>
@ -45,7 +45,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { defineComponent, onMounted, ref, useRoute, useContext, useStore, useAsync, ssrRef, shallowSsrRef, ssrPromise, useMeta } from '@nuxtjs/composition-api' import { useRoute, useContext, useStore, useAsync, ssrRef, shallowSsrRef, ssrPromise, useMeta } from '@nuxtjs/composition-api'
export default defineComponent({ export default defineComponent({
setup () { setup () {