Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!(nuxt): upgrade nuxt module #1435

Merged
merged 30 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
b5674b9
feat(nuxt)!: rewrite with nuxt/kit
pi0 Jul 8, 2022
e97bcb0
auto imports
pi0 Jul 8, 2022
d816163
update deps
pi0 Jul 8, 2022
2e75652
lint
pi0 Jul 8, 2022
a6534d3
use nuxi to typecheck nuxt
pi0 Jul 8, 2022
5919835
add vue-tsc devDependency
pi0 Jul 8, 2022
1a85c24
fix build script
pi0 Jul 8, 2022
0af4ebd
remove vue-demi
pi0 Jul 8, 2022
894d81d
simplify injections
pi0 Jul 8, 2022
45b9318
feat: usePinia composable
pi0 Jul 8, 2022
d49defb
refactor: use resolver
pi0 Jul 8, 2022
5d53d34
fix lint issues
pi0 Jul 8, 2022
ab14389
chore: add back the name and missing configs
posva Jul 8, 2022
826c7ec
wip: add incomplete missing types
posva Jul 8, 2022
21f4d05
ci: prepare types
posva Jul 8, 2022
873f79c
chore: format
posva Jul 8, 2022
607f76a
test(ts): add src folder
posva Jul 8, 2022
6fde230
chore: fix tsconfig
posva Jul 8, 2022
8c3b34e
test: remove failing types
posva Jul 8, 2022
74713bf
add missing peer dep
pi0 Jul 13, 2022
9849aed
feat(nuxt): remove wrong `$nuxt` in Nuxt 3
posva Jul 13, 2022
d630cb0
feat(nuxt): deprecate old `$nuxt` context
posva Jul 13, 2022
a15cf09
style: format comment
posva Jul 13, 2022
1ae5c41
docs: remove outdated nuxt section
posva Jul 13, 2022
1a01da6
docs: updated nuxt instructions
posva Jul 13, 2022
3d7b930
feat(nuxt): add `autoImports` option in module
posva Jul 13, 2022
08b8ccb
fix(nuxt): correct type for `$nuxt`
posva Jul 13, 2022
e0a1210
docs: update version
posva Jul 13, 2022
cbaf9de
chore: ok
posva Jul 13, 2022
5286aee
chore: up lock
posva Jul 13, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .npmrc
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
shamefully-hoist=true
strict-peer-dependencies=false
91 changes: 59 additions & 32 deletions packages/docs/ssr/nuxt.md
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# Nuxt.js

Using Pinia with [Nuxt.js](https://nuxtjs.org/) is easier since Nuxt takes care of a lot of things when it comes to _server side rendering_. For instance, **you don't need to care about serialization nor XSS attacks**.
Using Pinia with [Nuxt.js](https://nuxtjs.org/) is easier since Nuxt takes care of a lot of things when it comes to _server side rendering_. For instance, **you don't need to care about serialization nor XSS attacks**. Pinia supports Nuxt Bridge and Nuxt 3, for bare Nuxt 2 support, [See below](#nuxt-2-without-bridge).

## Installation

Make sure to install [`@nuxtjs/composition-api`](https://composition-api.nuxtjs.org/) alongside `pinia`:

```bash
yarn add pinia @pinia/nuxt @nuxtjs/composition-api
yarn add @pinia/nuxt
# or with npm
npm install pinia @pinia/nuxt @nuxtjs/composition-api
npm install @pinia/nuxt
```

We supply a _module_ to handle everything for you, you only need to add it to `buildModules` in your `nuxt.config.js` file:
Expand All @@ -19,9 +17,7 @@ We supply a _module_ to handle everything for you, you only need to add it to `b
export default {
// ... other options
buildModules: [
// Nuxt 2 only:
// https://composition-api.nuxtjs.org/getting-started/setup#quick-start
'@nuxtjs/composition-api/module',
// ...
'@pinia/nuxt',
],
}
Expand All @@ -43,37 +39,28 @@ export default {
}
```

## Using the Nuxt context in stores
## Auto imports

You can also use [the context](https://nuxtjs.org/docs/2.x/internals-glossary/context) in any store by using the injected property `$nuxt`:

```js
import { useUserStore } from '~/stores/userStore'

defineStore('cart', {
actions: {
purchase() {
const user = useUserStore()
if (!user.isAuthenticated()) {
this.$nuxt.redirect('/login')
}
},
},
})
```

## Using Pinia alongside Vuex

It is recommended to **avoid using both Pinia and Vuex** but if you need to use both, you need to tell pinia to not disable it:
By default `@pinia/nuxt` exposes one single auto import: `usePinia()`, which is similar to `getActivePinia()` but works better with Nuxt. You can add auto imports to make your life easier:

```js
// nuxt.config.js
export default {
// ... other options
buildModules: [
'@nuxtjs/composition-api/module',
['@pinia/nuxt', { disableVuex: false }],
// ...
[
'@pinia/nuxt',
{
autoImports: [
// automatically imports `usePinia()`
'defineStore',
// automatically imports `usePinia()` as `usePiniaStore()`
['defineStore', 'definePiniaStore'],
],
},
],
],
// ... other options
}
```

Expand All @@ -91,3 +78,43 @@ If you are using TypeScript or have a `jsconfig.json`, you should also add the t
```

This will also ensure you have autocompletion 😉 .

## Nuxt 2 without bridge

Pinia supports Nuxt 2 until `@pinia/nuxt` v0.2.1. Make sure to also install [`@nuxtjs/composition-api`](https://composition-api.nuxtjs.org/) alongside `pinia`:

```bash
yarn add pinia @pinia/nuxt@0.2.1 @nuxtjs/composition-api
# or with npm
npm install pinia @pinia/nuxt@0.2.1 @nuxtjs/composition-api
```

We supply a _module_ to handle everything for you, you only need to add it to `buildModules` in your `nuxt.config.js` file:

```js
// nuxt.config.js
export default {
// ... other options
buildModules: [
// Nuxt 2 only:
// https://composition-api.nuxtjs.org/getting-started/setup#quick-start
'@nuxtjs/composition-api/module',
'@pinia/nuxt',
],
}
```

### Using Pinia alongside Vuex

It is recommended to **avoid using both Pinia and Vuex** but if you need to use both, you need to tell pinia to not disable it:

```js
// nuxt.config.js
export default {
buildModules: [
'@nuxtjs/composition-api/module',
['@pinia/nuxt', { disableVuex: false }],
],
// ... other options
}
```
2 changes: 2 additions & 0 deletions packages/nuxt/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
.nuxt
.output
11 changes: 0 additions & 11 deletions packages/nuxt/build.config.ts

This file was deleted.

6 changes: 0 additions & 6 deletions packages/nuxt/module.cjs

This file was deleted.

34 changes: 17 additions & 17 deletions packages/nuxt/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,35 +24,35 @@
"email": "posva13@gmail.com"
},
"sideEffects": false,
"type": "module",
"exports": {
".": {
"import": "./dist/module.mjs",
"require": "./module.cjs"
},
"./dist/*": "./dist/*"
"require": "./dist/module.cjs"
}
},
"main": "./module.cjs",
"types": "./dist/module.d.ts",
"main": "./dist/module.cjs",
"types": "./dist/types.d.ts",
"files": [
"module.cjs",
"dist/*.js",
"dist/*.mjs",
"dist/*.d.ts"
"dist"
],
"scripts": {
"build": "unbuild",
"build": "pnpm dev:prepare && nuxt-module-build",
"dev": "nuxi dev playground",
"dev:build": "nuxi build playground",
"dev:prepare": "nuxt-module-build --stub && nuxi prepare playground",
"test:types": "pnpm dev:prepare && nuxi typecheck",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s --commit-path . -l @pinia/nuxt -r 1"
},
"dependencies": {
"vue-demi": "*"
"@nuxt/kit": "^3.0.0-rc.4",
"pinia": ">=2.0.14"
pi0 marked this conversation as resolved.
Show resolved Hide resolved
},
"devDependencies": {
"@nuxt/types": "^2.15.8",
"pinia": "^2.0.0",
"unbuild": "^0.7.4"
},
"peerDependencies": {
"pinia": ">=2.0.16"
"@nuxt/module-builder": "latest",
"nuxt": "^3.0.0-rc.4",
"typescript": "^4.6.3",
"vue-tsc": "^0.38.3"
},
"publishConfig": {
"access": "public"
Expand Down
14 changes: 14 additions & 0 deletions packages/nuxt/playground/app.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<script lang="ts" setup>
const counter = useCounter()

if (process.server) {
counter.increment()
}
</script>

<template>
<div>
<p>Count: {{ counter.$state.count }}</p>
<button @click="counter.increment()">+</button>
</div>
</template>
13 changes: 13 additions & 0 deletions packages/nuxt/playground/composables/counter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
export const useCounter = definePiniaStore('counter', {
state: () => ({
count: 100,
}),
actions: {
increment() {
this.count++
},
},
getters: {
getCount: (state) => state.count,
},
})
6 changes: 6 additions & 0 deletions packages/nuxt/playground/nuxt.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineNuxtConfig } from 'nuxt'
import piniaModule from '../src/module'

export default defineNuxtConfig({
modules: [piniaModule],
})
4 changes: 4 additions & 0 deletions packages/nuxt/playground/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"private": true,
"name": "pinia-nuxt-playground"
}
5 changes: 5 additions & 0 deletions packages/nuxt/shims.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
declare namespace NodeJS {
export interface Process {
server: boolean
}
}
117 changes: 65 additions & 52 deletions packages/nuxt/src/module.ts
Original file line number Diff line number Diff line change
@@ -1,70 +1,83 @@
/**
* @module @pinia/nuxt
*/
// import { isVue2 } from 'vue-demi'
import type { Pinia } from 'pinia'
import type { Context, Module } from '@nuxt/types'
import {
defineNuxtModule,
addPlugin,
isNuxt2,
addAutoImport,
createResolver,
} from '@nuxt/kit'

export interface PiniaNuxtOptions {
export interface ModuleOptions {
/**
* Pinia disables Vuex by default, set this option to `false` to avoid it and
* use Pinia alongside Vuex.
* use Pinia alongside Vuex (Nuxt 2 only)
*
* @default `true`
*/
disableVuex?: boolean
}

const DEFAULTS = {
disableVuex: true,
/**
* Array of auto imports to be added to the nuxt.config.js file.
*
* @example
* ```js
* autoImports: [
* // automatically import `defineStore`
* 'defineStore',
* // automatically import `defineStore` as `definePiniaStore`
* ['defineStore', 'definePiniaStore',
* ]
* ```
*
*/
autoImports?: Array<string | [string, string]>
}

export default <Module>function (_options) {
const nuxt = this.nuxt
const options = {
...DEFAULTS,
...(_options || {}),
...(nuxt.options.pinia || {}),
}
export default defineNuxtModule<ModuleOptions>({
meta: {
name: 'pinia',
configKey: 'pinia',
compatibility: {
nuxt: '^2.0.0 || ^3.0.0',
bridge: true,
},
},
defaults: {
disableVuex: true,
autoImports: [],
},
setup(options, nuxt) {
const resolver = createResolver(import.meta.url)

// Disable default Vuex store (options.features only exists in Nuxt v2.10+)
if (nuxt.options.features && options.disableVuex) {
nuxt.options.features.store = false
}
// Disable default Vuex store (Nuxt v2.10+ only)
if (nuxt.options.features && options.disableVuex && isNuxt2()) {
nuxt.options.features.store = false
}

// make sure we use the mjs for pinia so node doesn't complain about using a module js with an extension that is js
// but doesn't have the type: module in its packages.json file
nuxt.options.alias.pinia = 'pinia/dist/pinia.mjs'
// Transpile runtime
nuxt.options.build.transpile.push(resolver.resolve('./runtime'))

this.addPlugin({ src: require.resolve('./plugin.mjs') })
// Make sure we use the mjs build for pinia
nuxt.options.alias.pinia = 'pinia/dist/pinia.mjs'

// transpile pinia for nuxt 2 and nuxt bridge
// if (isVue2 && !nuxt.options.build.transpile.includes('pinia')) {
// nuxt.options.build.transpile.push('pinia')
// }
}

declare module '@nuxt/types' {
pi0 marked this conversation as resolved.
Show resolved Hide resolved
export interface Context {
/**
* Pinia instance attached to the app.
*
* @deprecated: use context.$pinia instead
*/
pinia: Pinia
// Add runtime plugin
if (isNuxt2()) {
addPlugin(resolver.resolve('./runtime/plugin.vue2'))
} else {
addPlugin(resolver.resolve('./runtime/plugin.vue3'))
}
pi0 marked this conversation as resolved.
Show resolved Hide resolved

/**
* Pinia instance attached to the app.
*/
$pinia: Pinia
}
}

declare module 'pinia' {
export interface PiniaCustomProperties {
/**
* Nuxt context.
*/
$nuxt: Context
}
}
// Add auto imports
const composables = resolver.resolve('./runtime/composables')
addAutoImport([
{ from: composables, name: 'usePinia' },
...options.autoImports.map((imports) =>
typeof imports === 'string'
? { from: composables, name: imports }
: { from: composables, name: imports[0], as: imports[1] }
),
])
},
})
4 changes: 4 additions & 0 deletions packages/nuxt/src/runtime/composables.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { useNuxtApp } from '#imports'
export * from 'pinia'

export const usePinia = () => useNuxtApp().$pinia
pi0 marked this conversation as resolved.
Show resolved Hide resolved
Loading