Skip to content
This repository has been archived by the owner on Apr 6, 2023. It is now read-only.

Commit

Permalink
Merge branch 'main' into fix/error-dx
Browse files Browse the repository at this point in the history
  • Loading branch information
pi0 authored Jul 21, 2022
2 parents e69bdf8 + 1a86252 commit 444a59c
Show file tree
Hide file tree
Showing 19 changed files with 894 additions and 866 deletions.
786 changes: 0 additions & 786 deletions .yarn/releases/yarn-3.2.1.cjs

This file was deleted.

783 changes: 783 additions & 0 deletions .yarn/releases/yarn-3.2.2.cjs

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion .yarnrc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ plugins:
- path: .yarn/plugins/@yarnpkg/plugin-interactive-tools.cjs
spec: "@yarnpkg/plugin-interactive-tools"

yarnPath: .yarn/releases/yarn-3.2.1.cjs
yarnPath: .yarn/releases/yarn-3.2.2.cjs
77 changes: 44 additions & 33 deletions docs/content/2.guide/3.directory-structure/5.composables.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,49 +8,21 @@ head.title: Composables directory

Nuxt 3 supports `composables/` directory to automatically import your Vue composables into your application using [auto-imports](/guide/concepts/auto-imports)!

## How files are scanned

Nuxt only scans files at the top level of the `composables/` directory (or index files within any subdirectories) for composables.

For example:

```bash
composables
| - useFoo.ts // scanned
| - useBar
| --- supportingFile.ts // not scanned
| --- index.ts // scanned
```

Only `useFoo.ts` and `useBar/index.ts` would be searched for imports - and if the latter is a default export, it would be registered as `useBar` rather than `index`.

To get auto imports for `useBar/supportingFile.ts`, you have to re-export the composables you need from the `useBar/index.ts` file.

```js [composables/useBar/index.ts]
export const useBar = () => {
}

// Enables auto import for this export
export { useBaz } from './supportingFile'
```

::alert{type=warning}
Auto import generating doesn't work with `export * from './supportingFile.ts'`, you must use named exports or a default export.
::

Under the hood, Nuxt auto generates the file `.nuxt/auto-imports.d.ts` to declare the types.

Be aware that you have to run `nuxi prepare`, `nuxi dev` or `nuxi build` in order to let Nuxt generates the types. If you create a composable without having the dev server running, typescript will throw an error `Cannot find name 'useBar'.`

## Example: (using named export)
## Example

**Method 1:** Using named export

```js [composables/useFoo.ts]
export const useFoo = () => {
return useState('foo', () => 'bar')
}
```

## Example: (using default export)
**Method 2:** Using default export

```js [composables/use-foo.ts or composables/useFoo.ts]
// It will be available as useFoo() (camelCase of file name without extension)
Expand All @@ -59,7 +31,7 @@ export default function () {
}
```

You can now auto-import it:
**Usage:** You can now use auto imported composable in `.js`, `.ts` and `.vue` files

```vue [app.vue]
<template>
Expand All @@ -74,3 +46,42 @@ const foo = useFoo()
```

:LinkExample{link="/examples/auto-imports/composables"}

## How files are scanned

Nuxt only scans files at the top level of the `composables/` directory for composables.

For example:

```bash
composables
| - useFoo.ts // scanned
| - index.ts // scanned
| - nested
| --- utils.ts // not scanned
```

Only `composables/useFoo.ts` would be searched for imports.

To get auto imports for nested modules, you could either reexport them (recommended) or configure the scanner to scan nested directories:

**Example:** re-export the composables you need from the `composables/index.ts` file:

```js [composables/index.ts]
// Enables auto import for this export
export { useBaz } from './nested/useBaz.ts'
```

**Example:** Scan nested directories inside composables:

```ts [nuxt.config.ts]
export default defineConfig({
// ...
autoImports: {
dirs: [
// Scan composables from nested directories
'composables/**'
]
}
})
```
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
"nuxi": "link:./packages/nuxi",
"nuxt": "link:./packages/nuxt",
"nuxt3": "link:./packages/nuxt",
"vite": "~3.0.0",
"vite": "~3.0.2",
"unbuild": "^0.7.6"
},
"devDependencies": {
Expand All @@ -67,7 +67,7 @@
"vitest": "^0.18.1",
"vue-tsc": "^0.38.9"
},
"packageManager": "[email protected].1",
"packageManager": "[email protected].2",
"engines": {
"node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0"
}
Expand Down
2 changes: 1 addition & 1 deletion packages/kit/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
"scule": "^0.2.1",
"semver": "^7.3.7",
"unctx": "^1.1.4",
"unimport": "^0.4.5",
"unimport": "^0.6.1",
"untyped": "^0.4.4"
},
"devDependencies": {
Expand Down
3 changes: 2 additions & 1 deletion packages/kit/src/plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { normalize } from 'pathe'
import type { NuxtPlugin, NuxtPluginTemplate } from '@nuxt/schema'
import { useNuxt } from './context'
import { addTemplate } from './template'
import { resolveAlias } from './resolve'

/**
* Normalize a nuxt plugin object
Expand All @@ -19,7 +20,7 @@ export function normalizePlugin (plugin: NuxtPlugin | string): NuxtPlugin {
}

// Normalize full path to plugin
plugin.src = normalize(plugin.src)
plugin.src = normalize(resolveAlias(plugin.src))

// Normalize mode
if (plugin.ssr) {
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@
"ufo": "^0.8.5",
"unctx": "^1.1.4",
"unenv": "^0.5.2",
"unimport": "^0.4.5",
"unimport": "^0.6.1",
"unplugin": "^0.7.2",
"untyped": "^0.4.4",
"vue": "^3.2.37",
Expand Down
3 changes: 2 additions & 1 deletion packages/nuxt/src/auto-imports/module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
const ctx = createUnimport({
presets: options.presets,
imports: options.imports,
virtualImports: ['#imports'],
addons: {
vueTemplate: true
}
Expand All @@ -58,7 +59,7 @@ export default defineNuxtModule<Partial<AutoImportsOptions>>({
// Support for importing from '#imports'
addTemplate({
filename: 'imports.mjs',
getContents: () => ctx.toExports()
getContents: () => ctx.toExports() + '\nif (process.dev) { console.warn("[nuxt] `#imports` should be transformed with real imports. There seems to be something wrong with the auto-imports plugin.") }'
})
nuxt.options.alias['#imports'] = join(nuxt.options.buildDir, 'imports')

Expand Down
34 changes: 21 additions & 13 deletions packages/nuxt/src/auto-imports/transform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { createUnplugin } from 'unplugin'
import { parseQuery, parseURL } from 'ufo'
import { Unimport } from 'unimport'
import { AutoImportsOptions } from '@nuxt/schema'
import { normalize } from 'pathe'

export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx: Unimport, options: Partial<AutoImportsOptions>, sourcemap?: boolean }) => {
return {
Expand All @@ -12,35 +13,42 @@ export const TransformPlugin = createUnplugin(({ ctx, options, sourcemap }: {ctx
const { pathname, search } = parseURL(decodeURIComponent(pathToFileURL(id).href))
const { type, macro } = parseQuery(search)

const exclude = options.transform?.exclude || [/[\\/]node_modules[\\/]/]
const include = options.transform?.include || []

// Custom includes - exclude node_modules by default
if (exclude.some(pattern => id.match(pattern)) && !include.some(pattern => id.match(pattern))) {
// Included
if (options.transform?.include?.some(pattern => id.match(pattern))) {
return true
}
// Excluded
if (options.transform?.exclude?.some(pattern => id.match(pattern))) {
return false
}

// vue files
// Vue files
if (
pathname.endsWith('.vue') &&
(type === 'template' || type === 'script' || macro || !search)
) {
return true
}

// js files
// JavaScript files
if (pathname.match(/\.((c|m)?j|t)sx?$/g)) {
return true
}
},
async transform (_code, id) {
const { code, s } = await ctx.injectImports(_code, id)
if (code === _code) {
async transform (code, id) {
id = normalize(id)
const isNodeModule = id.match(/[\\/]node_modules[\\/]/) && !options.transform?.include?.some(pattern => id.match(pattern))
// For modules in node_modules, we only transform `#imports` but not doing auto-imports
if (isNodeModule && !code.match(/(['"])#imports\1/)) {
return
}
return {
code,
map: sourcemap && s.generateMap({ source: id, includeContent: true })

const { s } = await ctx.injectImports(code, id, { autoImport: !isNodeModule })
if (s.hasChanged()) {
return {
code: s.toString(),
map: sourcemap && s.generateMap({ source: id, includeContent: true })
}
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion packages/nuxt/src/core/nitro.ts
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ export async function initNitro (nuxt: Nuxt) {

// Add typed route responses
nuxt.hook('prepare:types', async (opts) => {
if (nuxt.options._prepare) {
if (!nuxt.options.dev) {
await scanHandlers(nitro)
await writeTypes(nitro)
}
Expand Down
4 changes: 3 additions & 1 deletion packages/nuxt/src/pages/macros.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,8 @@ const starts = {
"'": "'"
}

const QUOTE_RE = /["']/

function extractObject (code: string) {
// Strip comments
code = code.replace(/^\s*\/\/.*$/gm, '')
Expand All @@ -107,7 +109,7 @@ function extractObject (code: string) {
do {
if (stack[0] === code[0] && result.slice(-1) !== '\\') {
stack.shift()
} else if (code[0] in starts) {
} else if (code[0] in starts && !QUOTE_RE.test(stack[0])) {
stack.unshift(starts[code[0]])
}
result += code[0]
Expand Down
4 changes: 2 additions & 2 deletions packages/schema/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"@types/lodash.template": "^4",
"@types/semver": "^7",
"unbuild": "latest",
"vite": "~3.0.0"
"vite": "~3.0.2"
},
"dependencies": {
"c12": "^0.2.8",
Expand All @@ -29,7 +29,7 @@
"scule": "^0.2.1",
"std-env": "^3.1.1",
"ufo": "^0.8.5",
"unimport": "^0.4.5"
"unimport": "^0.6.1"
},
"engines": {
"node": "^14.16.0 || ^16.11.0 || ^17.0.0 || ^18.0.0"
Expand Down
4 changes: 2 additions & 2 deletions packages/vite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@
"dependencies": {
"@nuxt/kit": "^3.0.0-rc.6",
"@rollup/plugin-replace": "^4.0.0",
"@vitejs/plugin-vue": "^3.0.0",
"@vitejs/plugin-vue": "^3.0.1",
"@vitejs/plugin-vue-jsx": "^2.0.0",
"autoprefixer": "^10.4.7",
"chokidar": "^3.5.3",
Expand All @@ -47,7 +47,7 @@
"rollup-plugin-visualizer": "^5.7.1",
"ufo": "^0.8.5",
"unplugin": "^0.7.2",
"vite": "~3.0.0",
"vite": "~3.0.2",
"vite-node": "^0.18.1",
"vite-plugin-checker": "^0.4.9"
},
Expand Down
2 changes: 1 addition & 1 deletion packages/vite/src/vite.ts
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ export async function bundle (nuxt: Nuxt) {
// Invalidate virtual modules when templates are re-generated
ctx.nuxt.hook('app:templatesGenerated', () => {
for (const [id, mod] of server.moduleGraph.idToModuleMap) {
if (id.startsWith('\x00virtual:')) {
if (id.startsWith('virtual:')) {
server.moduleGraph.invalidateModule(mod)
}
}
Expand Down
5 changes: 5 additions & 0 deletions test/fixtures/basic/composables/badSideEffect.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export function badSideEffect () {
// ...
}

throw new Error('composables/badSideEffect.ts should be tree-shaked')
2 changes: 2 additions & 0 deletions test/fixtures/basic/pages/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
</template>

<script setup>
import { useRuntimeConfig } from '#imports'
const config = useRuntimeConfig()
const foo = useFoo()
Expand Down
1 change: 1 addition & 0 deletions test/fixtures/basic/pages/no-auth.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<script setup>
definePageMeta({
title: "l'equipe"
// middleware: 'inject-auth'
})
</script>
Expand Down
Loading

0 comments on commit 444a59c

Please sign in to comment.