├── .editorconfig
├── .eslintignore
├── .eslintrc.js
├── .github
├── ISSUE_TEMPLATE
│ ├── bug_report.md
│ └── feature_request.md
└── workflows
│ └── test.yml
├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── docs
├── .gitignore
├── assets
│ └── custom.css
├── components
│ └── global
│ │ ├── Example.vue
│ │ └── InjectCode.vue
├── content
│ ├── en
│ │ ├── cookbook
│ │ │ ├── components.md
│ │ │ ├── configuration.md
│ │ │ ├── middlewares.md
│ │ │ ├── modules.md
│ │ │ ├── plugins.md
│ │ │ ├── server-middlewares.md
│ │ │ └── store.md
│ │ ├── examples
│ │ │ ├── class-api
│ │ │ │ ├── basic.md
│ │ │ │ └── minimal.md
│ │ │ ├── composition-api
│ │ │ │ ├── basic.md
│ │ │ │ └── minimal.md
│ │ │ └── options-api
│ │ │ │ ├── basic.md
│ │ │ │ └── minimal.md
│ │ ├── guide
│ │ │ ├── introduction.md
│ │ │ ├── lint.md
│ │ │ ├── runtime.md
│ │ │ └── setup.md
│ │ └── index.md
│ ├── es
│ │ ├── cookbook
│ │ │ ├── components.md
│ │ │ ├── configuration.md
│ │ │ ├── middlewares.md
│ │ │ ├── modules.md
│ │ │ ├── plugins.md
│ │ │ ├── server-middlewares.md
│ │ │ └── store.md
│ │ ├── examples
│ │ │ ├── class-api
│ │ │ │ └── minimal.md
│ │ │ ├── composition-api
│ │ │ │ └── minimal.md
│ │ │ └── options-api
│ │ │ │ └── minimal.md
│ │ ├── guide
│ │ │ ├── introduction.md
│ │ │ ├── lint.md
│ │ │ ├── runtime.md
│ │ │ └── setup.md
│ │ └── index.md
│ ├── ja
│ │ ├── cookbook
│ │ │ ├── components.md
│ │ │ ├── configuration.md
│ │ │ ├── middlewares.md
│ │ │ ├── modules.md
│ │ │ ├── plugins.md
│ │ │ ├── server-middlewares.md
│ │ │ └── store.md
│ │ ├── examples
│ │ │ ├── class-api
│ │ │ │ └── minimal.md
│ │ │ ├── composition-api
│ │ │ │ └── minimal.md
│ │ │ └── options-api
│ │ │ │ └── minimal.md
│ │ ├── guide
│ │ │ ├── introduction.md
│ │ │ ├── lint.md
│ │ │ ├── runtime.md
│ │ │ └── setup.md
│ │ └── index.md
│ ├── pt
│ │ ├── cookbook
│ │ │ ├── components.md
│ │ │ ├── configuration.md
│ │ │ ├── middlewares.md
│ │ │ ├── modules.md
│ │ │ ├── plugins.md
│ │ │ ├── server-middlewares.md
│ │ │ └── store.md
│ │ ├── examples
│ │ │ ├── class-api
│ │ │ │ └── minimal.md
│ │ │ ├── composition-api
│ │ │ │ └── minimal.md
│ │ │ └── options-api
│ │ │ │ └── minimal.md
│ │ ├── guide
│ │ │ ├── introduction.md
│ │ │ ├── lint.md
│ │ │ ├── runtime.md
│ │ │ └── setup.md
│ │ └── index.md
│ ├── settings.json
│ ├── shared
│ │ ├── components
│ │ │ ├── script.class-api.ts.md
│ │ │ ├── script.composition-api.ts.md
│ │ │ ├── script.options-api.ts.md
│ │ │ └── template.html.md
│ │ └── tsconfig.json.md
│ ├── zh-Hans
│ │ ├── cookbook
│ │ │ ├── components.md
│ │ │ ├── configuration.md
│ │ │ ├── middlewares.md
│ │ │ ├── modules.md
│ │ │ ├── plugins.md
│ │ │ ├── server-middlewares.md
│ │ │ └── store.md
│ │ ├── examples
│ │ │ ├── class-api
│ │ │ │ └── minimal.md
│ │ │ ├── composition-api
│ │ │ │ └── minimal.md
│ │ │ └── options-api
│ │ │ │ └── minimal.md
│ │ ├── guide
│ │ │ ├── introduction.md
│ │ │ ├── lint.md
│ │ │ ├── runtime.md
│ │ │ └── setup.md
│ │ └── index.md
│ └── zh-Hant
│ │ ├── cookbook
│ │ ├── components.md
│ │ ├── configuration.md
│ │ ├── middlewares.md
│ │ ├── modules.md
│ │ ├── plugins.md
│ │ ├── server-middlewares.md
│ │ └── store.md
│ │ ├── examples
│ │ ├── class-api
│ │ │ └── minimal.md
│ │ ├── composition-api
│ │ │ └── minimal.md
│ │ └── options-api
│ │ │ └── minimal.md
│ │ ├── guide
│ │ ├── introduction.md
│ │ ├── lint.md
│ │ ├── runtime.md
│ │ └── setup.md
│ │ └── index.md
├── nuxt.config.js
├── package.json
├── plugins
│ └── vue-tabs.js
├── static
│ ├── favicon.ico
│ ├── icon.png
│ └── icon.svg
├── tailwind.config.js
└── yarn.lock
├── examples
├── class-api
│ ├── basic
│ │ ├── README.md
│ │ ├── nuxt.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ └── index.vue
│ │ └── tsconfig.json
│ └── minimal
│ │ ├── README.md
│ │ ├── nuxt.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ └── index.vue
│ │ └── tsconfig.json
├── composition-api
│ ├── basic
│ │ ├── README.md
│ │ ├── nuxt.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ │ └── index.vue
│ │ ├── plugins
│ │ │ └── composition-api.js
│ │ └── tsconfig.json
│ └── minimal
│ │ ├── README.md
│ │ ├── nuxt.config.js
│ │ ├── package.json
│ │ ├── pages
│ │ └── index.vue
│ │ ├── plugins
│ │ └── composition-api.js
│ │ └── tsconfig.json
└── options-api
│ ├── basic
│ ├── README.md
│ ├── nuxt.config.js
│ ├── package.json
│ ├── pages
│ │ └── index.vue
│ └── tsconfig.json
│ └── minimal
│ ├── README.md
│ ├── nuxt.config.js
│ ├── package.json
│ ├── pages
│ └── index.vue
│ └── tsconfig.json
├── jest.config.js
├── lerna.json
├── netlify.toml
├── package.json
├── packages
├── typescript-build
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── package.json
│ ├── src
│ │ └── index.ts
│ ├── test
│ │ ├── fixture
│ │ │ ├── @types
│ │ │ │ └── vue.d.ts
│ │ │ ├── nuxt.config.ts
│ │ │ ├── pages
│ │ │ │ ├── about.ts
│ │ │ │ ├── contact.tsx
│ │ │ │ ├── index.vue
│ │ │ │ └── interface.vue
│ │ │ ├── serverMiddlewares
│ │ │ │ └── logger.ts
│ │ │ ├── shims-tsx.d.ts
│ │ │ └── tsconfig.json
│ │ └── module.test.ts
│ └── tsconfig.json
└── typescript-runtime
│ ├── CHANGELOG.md
│ ├── README.md
│ ├── bin
│ └── nuxt-ts.js
│ ├── package.json
│ ├── src
│ └── index.ts
│ ├── test
│ └── hooks.test.ts
│ └── tsconfig.json
├── renovate.json
├── tsconfig.json
├── tsconfig.test.json
└── yarn.lock
/.editorconfig:
--------------------------------------------------------------------------------
1 | # editorconfig.org
2 | root = true
3 |
4 | [*]
5 | indent_size = 2
6 | indent_style = space
7 | end_of_line = lf
8 | charset = utf-8
9 | trim_trailing_whitespace = true
10 | insert_final_newline = true
11 |
12 | [*.md]
13 | trim_trailing_whitespace = false
14 |
--------------------------------------------------------------------------------
/.eslintignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .nuxt
4 | static
5 | coverage
6 |
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | extends: [
3 | '@nuxtjs/eslint-config-typescript'
4 | ]
5 | }
6 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/bug_report.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Bug report
3 | about: Create a report to help us improve
4 | title: ''
5 | labels: ''
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Describe the bug**
11 | A clear and concise description of what the bug is.
12 |
13 | **To Reproduce**
14 | Steps to reproduce the behavior:
15 | 1. Clone repository '...'
16 | 2. Run '....'
17 | 3. See error
18 |
19 | **Expected behavior**
20 | A clear and concise description of what you expected to happen.
21 |
22 | **Screenshots**
23 | If applicable, add screenshots to help explain your problem.
24 |
25 | **Additional context**
26 | Add any other context about the problem here.
27 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/feature_request.md:
--------------------------------------------------------------------------------
1 | ---
2 | name: Feature request
3 | about: Suggest an idea for this project
4 | title: ''
5 | labels: feature request
6 | assignees: ''
7 |
8 | ---
9 |
10 | **Is your feature request related to a problem? Please describe.**
11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
12 |
13 | **Describe the solution you'd like**
14 | A clear and concise description of what you want to happen.
15 |
16 | **Describe alternatives you've considered**
17 | A clear and concise description of any alternative solutions or features you've considered.
18 |
19 | **Additional context**
20 | Add any other context or screenshots about the feature request here.
21 |
--------------------------------------------------------------------------------
/.github/workflows/test.yml:
--------------------------------------------------------------------------------
1 | name: Test
2 |
3 | on:
4 | push:
5 | branches:
6 | - master
7 | pull_request:
8 | branches:
9 | - master
10 |
11 | jobs:
12 | test:
13 | runs-on: ubuntu-latest
14 |
15 | steps:
16 | - uses: actions/checkout@master
17 |
18 | - uses: actions/cache@v1
19 | id: cache
20 | with:
21 | path: "node_modules"
22 | key: ${{ runner.os }}-${{ hashFiles('yarn.lock') }}
23 |
24 | - name: Install dependencies
25 | if: steps.cache.outputs.cache-hit != 'true'
26 | run: yarn
27 |
28 | - name: Run tests
29 | run: yarn test
30 |
31 | - name: Coverage
32 | run: yarn codecov
33 | env:
34 | CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }}
35 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # Dependencies
2 | node_modules
3 |
4 | # Only keep yarn.lock in the root
5 | */**/yarn.lock
6 |
7 | # Logs
8 | *.log
9 |
10 | # Other
11 | .nuxt*
12 | !.nuxtignore
13 |
14 | # Dist folders
15 | dist
16 |
17 | # Coverage reports
18 | coverage
19 |
20 | # VSCode
21 | .vscode
22 |
23 | # Intellij idea
24 | *.iml
25 | .idea
26 |
27 | # OSX
28 | .DS_Store
29 | .AppleDouble
30 | .LSOverride
31 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2016-2019 Nuxt.js Team
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 | # Nuxt Typescript
13 |
14 | Documentation: https://typescript.nuxtjs.org
15 |
16 | ## 📑 License
17 |
18 | [MIT License](./LICENSE)
19 |
20 | Copyright (c) Nuxt.js Team
21 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | function isBabelLoader (caller) {
2 | return caller && caller.name === 'babel-loader'
3 | }
4 |
5 | module.exports = function (api) {
6 | if (api.env('test') && !api.caller(isBabelLoader)) {
7 | return {
8 | presets: [
9 | ['@babel/env', {
10 | targets: {
11 | node: 'current'
12 | }
13 | }]
14 | ]
15 | }
16 | }
17 | return {}
18 | }
19 |
--------------------------------------------------------------------------------
/docs/.gitignore:
--------------------------------------------------------------------------------
1 | static/sw.js
2 |
--------------------------------------------------------------------------------
/docs/assets/custom.css:
--------------------------------------------------------------------------------
1 | li a[href="/"],
2 | li a[href="/es"],
3 | li a[href="/ja"],
4 | li a[href="/pt"],
5 | li a[href="/zh-Hant"],
6 | li a[href="/zh-Hans"] {
7 | @apply -ml-2 mb-2 text-gray-500 uppercase tracking-wider font-bold text-sm;
8 |
9 | @screen lg {
10 | @apply text-xs;
11 | }
12 | }
13 |
14 | aside > div > ul {
15 | @screen lg {
16 | padding-left: 0.5rem !important;
17 | }
18 | }
19 |
20 | .prose {
21 | pre code::after {
22 | @apply absolute;
23 | }
24 |
25 | img[src*="img.shields.io"] {
26 | display: inline !important;
27 | }
28 | }
29 |
30 | .tabs-component {
31 | @apply my-16 mx-0
32 | }
33 |
34 | .tabs-component-tabs {
35 | @apply z-10 bg-tabs px-2 rounded-t-md mb-0 !important;
36 |
37 | @screen md {
38 | @apply flex justify-start items-stretch;
39 | }
40 | }
41 |
42 | .tabs-component-tab {
43 | @apply font-bold font-mono pl-0 mr-0 mt-0 mb-0 list-none !important;
44 | }
45 |
46 | .tabs-component-tab::before {
47 | @apply hidden;
48 | }
49 |
50 | .tabs-component-tab.is-active {
51 | border-bottom-style: solid;
52 | @apply border-b-2 border-tabs-active z-10;
53 | }
54 |
55 | .tabs-component-tab.is-disabled * {
56 | @apply cursor-not-allowed text-opacity-50 !important;
57 | }
58 |
59 | .tabs-component-tab-a {
60 | @apply flex items-center no-underline px-4 py-3 text-sm text-gray-400 !important;
61 | }
62 |
63 | .tabs-component-panels {
64 | @apply bg-tabs p-4 rounded-none text-white rounded-b-md border-solid border-l-0 border-r-0 border-b-0 border-t-2 border-tabs-separator transform -translate-y-2;
65 | }
--------------------------------------------------------------------------------
/docs/components/global/Example.vue:
--------------------------------------------------------------------------------
1 |
2 |
13 |
14 |
15 |
30 |
31 |
59 |
--------------------------------------------------------------------------------
/docs/components/global/InjectCode.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
18 |
19 |
22 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/components.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Components
3 | position: 20
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | In [**Single File Components (SFC)**](https://vuejs.org/v2/guide/single-file-components.html), `script` tags must specify the `ts` language:
9 | ```html
10 |
13 | ```
14 |
15 | ## Template
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Using [@vue/composition-api](https://github.com/vuejs/composition-api) plugin
29 |
30 |
31 |
32 | **Plugin installation**
33 |
34 | ```js{}[plugins/composition-api.js]
35 | import Vue from 'vue'
36 | import VueCompositionApi from '@vue/composition-api'
37 |
38 | Vue.use(VueCompositionApi)
39 | ```
40 |
41 | ```js{}[nuxt.config.js]
42 | export default {
43 | plugins: ['@/plugins/composition-api']
44 | }
45 | ```
46 |
47 | This plugin registration is mandatory to make `setup` function works in components.
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Using [vue-class-component](https://github.com/vuejs/vue-class-component) through [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator)
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuration (Runtime)
3 | position: 26
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // Define your configuration with auto-completion & type checking
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Middlewares
3 | position: 23
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // Use context
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Modules (Runtime)
3 | position: 27
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // Use this, this.options, this.nuxt
19 | // Use moduleOptions
20 | }
21 |
22 | export default myModule
23 |
24 | // REQUIRED if publishing the module as npm package
25 | // export const meta = require('./package.json')
26 | ```
27 |
28 | Read more about [modules property](https://nuxtjs.org/docs/configuration-glossary/configuration-modules/), [modules dir](https://nuxtjs.org/docs/directory-structure/modules/).
29 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Plugins
3 | position: 24
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | ## I. Inject into Vue instances
9 |
10 | ### Plugin
11 |
12 | ```ts
13 | import Vue from 'vue'
14 |
15 | declare module 'vue/types/vue' {
16 | interface Vue {
17 | $myInjectedFunction(message: string): void
18 | }
19 | }
20 |
21 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
22 | ```
23 |
24 | ### Usage
25 |
26 | ```html
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 | ```
44 |
45 | ## II. Inject into context
46 |
47 | ### Plugin
48 |
49 | ```ts
50 | import { Plugin } from '@nuxt/types'
51 |
52 | declare module '@nuxt/types' {
53 | interface Context {
54 | $myInjectedFunction(message: string): void
55 | }
56 | }
57 |
58 | const myPlugin: Plugin = (context) => {
59 | context.$myInjectedFunction = (message: string) => console.log(message)
60 | }
61 |
62 | export default myPlugin
63 | ```
64 |
65 | ### Usage
66 |
67 | ```html
68 |
77 | ```
78 |
79 | ## III. Combined Inject
80 |
81 | ### Plugin
82 |
83 | ```ts
84 | import { Plugin } from '@nuxt/types'
85 |
86 | declare module 'vue/types/vue' {
87 | // this.$myInjectedFunction inside Vue components
88 | interface Vue {
89 | $myInjectedFunction(message: string): void
90 | }
91 | }
92 |
93 | declare module '@nuxt/types' {
94 | // nuxtContext.app.$myInjectedFunction inside asyncData, fetch, plugins, middleware, nuxtServerInit
95 | interface NuxtAppOptions {
96 | $myInjectedFunction(message: string): void
97 | }
98 | // nuxtContext.$myInjectedFunction
99 | interface Context {
100 | $myInjectedFunction(message: string): void
101 | }
102 | }
103 |
104 | declare module 'vuex/types/index' {
105 | // this.$myInjectedFunction inside Vuex stores
106 | interface Store {
107 | $myInjectedFunction(message: string): void
108 | }
109 | }
110 |
111 | const myPlugin: Plugin = (context, inject) => {
112 | inject('myInjectedFunction', (message: string) => console.log(message))
113 | }
114 |
115 | export default myPlugin
116 | ```
117 |
118 | ### Usage
119 |
120 | ```html
121 |
133 | ```
134 |
135 |
136 |
137 | Please note that `inject` doesn't inject in `context` but in `context.app`.
138 |
139 |
140 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server Middlewares (Runtime)
3 | position: 28
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // Use req, res, next
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/en/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Store
3 | position: 25
4 | description: TypeScript Support for Nuxt.js
5 | category: Cookbook
6 | ---
7 |
8 | There are a number of different options for writing and accessing the store in a Nuxt project using TypeScript.
9 |
10 | ## Class-based
11 |
12 | ### `vuex-module-decorators`
13 |
14 | One of the most popular approaches is [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) - see [guide](https://championswimmer.in/vuex-module-decorators/).
15 |
16 |
17 | For use with Nuxt, there are few key provisions:
18 |
19 | 1. Your modules must be decorated with `stateFactory: true`, so for example:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. If you want to access the store without initialising it in each component, you can do so using an [initialiser plugin](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs), for example:
44 | ```ts{}[store/index.ts]
45 | import { Store } from 'vuex'
46 | import { initialiseStores } from '~/utils/store-accessor'
47 |
48 | const initializer = (store: Store) => initialiseStores(store)
49 |
50 | export const plugins = [initializer]
51 | export * from '~/utils/store-accessor'
52 | ```
53 |
54 | 3. If you want to access the Nuxt app instance, you will need to do something similar with a plugin, for example:
55 | ```ts{}[plugins/axios-accessor.ts]
56 | import { Plugin } from '@nuxt/types'
57 | import { initializeAxios } from '~/utils/api'
58 |
59 | const accessor: Plugin = ({ $axios }) => {
60 | initializeAxios($axios)
61 | }
62 |
63 | export default accessor
64 | ```
65 |
66 | Don't forget to add the plugin to your `nuxt.config.js` file.
67 |
68 | ```ts{}[utils/api.ts]
69 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
70 |
71 | let $axios: NuxtAxiosInstance
72 |
73 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
74 | $axios = axiosInstance
75 | }
76 |
77 | export { $axios }
78 | ```
79 |
80 | ```ts{}[store/users.ts]
81 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
82 | import { $axios } from '~/utils/api'
83 | import { User } from '~/types'
84 |
85 | @Module({
86 | name: 'users',
87 | stateFactory: true,
88 | namespaced: true,
89 | })
90 | class UserModule extends VuexModule {
91 | users: User[] = []
92 |
93 | @Mutation
94 | setUsers(users: User[]) {
95 | this.users = users
96 | }
97 |
98 | @Action
99 | async getUsers() {
100 | const users = await $axios.$get('/users')
101 | this.setUsers(users)
102 | }
103 | }
104 | ```
105 |
106 | ### `vuex-class-component`
107 |
108 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) is a very promising class-based approach to the Nuxt store, and the syntax is very similar to `vuex-module-decorators`. It has just released a new API, although it is not yet compatible in its entirety with Nuxt. The workaround is to define modules with a decorator:
109 |
110 | ```ts
111 | @Module({ namespacedPath: 'foo' })
112 | export default class extends VuexModule {}
113 | ```
114 |
115 | See [this issue](https://github.com/michaelolof/vuex-class-component/issues/43) for the current status of the compatibility issue with Nuxt.
116 |
117 | ## Vanilla
118 |
119 | ### Basic typing
120 |
121 | Vuex supplies very basic types for use with the store. You can use these to help define your store. For example:
122 |
123 | ```ts{}[store/index.ts]
124 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
125 |
126 | export const state = () => ({
127 | things: [] as string[],
128 | name: 'Me',
129 | })
130 |
131 | export type RootState = ReturnType
132 |
133 | export const getters: GetterTree = {
134 | name: state => state.name,
135 | }
136 |
137 | export const mutations: MutationTree = {
138 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
139 | }
140 |
141 | export const actions: ActionTree = {
142 | async fetchThings({ commit }) {
143 | const things = await this.$axios.$get('/things')
144 | console.log(things)
145 | commit('CHANGE_NAME', 'New name')
146 | },
147 | }
148 | ```
149 |
150 | You would do exactly the same for a module. For example:
151 |
152 | `~/store/anotherModule.ts`:
153 | ```ts
154 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
155 | import { RootState } from '~/store'
156 |
157 | export const state = () => ({
158 | more: 3,
159 | })
160 |
161 | export type AnotherModuleState = ReturnType
162 |
163 | export const getters: GetterTree = {
164 | evenMore: state => state.more + 5,
165 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
166 | }
167 |
168 | export const actions: ActionTree = {
169 | printRootState({ rootState }) {
170 | console.log('accessing rootState:', rootState.name)
171 | },
172 | }
173 | ```
174 |
175 | ### Accessing the store
176 |
177 | #### `nuxt-typed-vuex`
178 |
179 | Vuex does not provide useful types for accessing the store from your app. `this.$store` remains untyped in a Nuxt app.
180 |
181 | There is a new project, [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) - and [guide](https://nuxt-typed-vuex.danielcroe.com/) - which aims to remedy that - providing a strongly-typed accessor for a vanilla Nuxt store.
182 |
183 | #### Bring your own
184 |
185 | Alternatively, you can provide your own types at the point of use.
186 |
187 | ```ts{}[components/MyComponent.vue]
188 |
13 | ```
14 |
15 | ## Template
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | Usando el plugin [@vue/composition-api](https://github.com/vuejs/composition-api)
31 |
32 |
33 |
34 | **Instalacion del Plugin**
35 |
36 | ```js{}[plugins/composition-api.js]
37 | import Vue from 'vue'
38 | import VueCompositionApi from '@vue/composition-api'
39 |
40 | Vue.use(VueCompositionApi)
41 | ```
42 |
43 | ```js{}[nuxt.config.js]
44 | export default {
45 | plugins: ['@/plugins/composition-api']
46 | }
47 | ```
48 |
49 | La instalación de este plugin es obligatorio para que la función `setup` funcione en componentes.
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | Usando [vue-class-component](https://github.com/vuejs/vue-class-component) mediante [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator)
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuración (Tiempo de Ejecución)
3 | position: 26
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // Defina tu configuracion con auto completado y verificación de tipos
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Middlewares
3 | position: 23
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // Use context
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Modules (Tiempo de Ejecución)
3 | position: 27
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // Usar this, this.options, this.nuxt
19 | // Usar moduleOptions
20 | }
21 |
22 | export default myModule
23 |
24 | // REQUERIDO si usted va a publicar el módulo como un paquete de npm
25 | // export const meta = require('./package.json')
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Plugins
3 | position: 24
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ## I. Inyectar en las instancias de Vue
9 |
10 | ### Plugin
11 |
12 | ```ts
13 | import Vue from 'vue'
14 |
15 | declare module 'vue/types/vue' {
16 | interface Vue {
17 | $myInjectedFunction(message: string): void
18 | }
19 | }
20 |
21 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
22 | ```
23 |
24 | ### Uso
25 |
26 | ```html
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 | ```
44 |
45 | ## II. Inyecta en el context
46 |
47 | ### Plugin
48 |
49 | ```ts
50 | import { Plugin } from '@nuxt/types'
51 |
52 | declare module '@nuxt/types' {
53 | interface Context {
54 | $myInjectedFunction(message: string): void
55 | }
56 | }
57 |
58 | const myPlugin: Plugin = (context) => {
59 | context.$myInjectedFunction = (message: string) => console.log(message)
60 | }
61 |
62 | export default myPlugin
63 | ```
64 |
65 | ### Uso
66 |
67 | ```html
68 |
77 | ```
78 |
79 | ## III. Inyección combinada
80 |
81 | ### Plugin
82 |
83 | ```ts
84 | import { Plugin } from '@nuxt/types'
85 |
86 | declare module 'vue/types/vue' {
87 | // this.$myInjectedFunction inside Vue components
88 | interface Vue {
89 | $myInjectedFunction(message: string): void
90 | }
91 | }
92 |
93 | declare module '@nuxt/types' {
94 | // nuxtContext.app.$myInjectedFunction inside asyncData, fetch, plugins, middleware, nuxtServerInit
95 | interface NuxtAppOptions {
96 | $myInjectedFunction(message: string): void
97 | }
98 | // nuxtContext.$myInjectedFunction
99 | interface Context {
100 | $myInjectedFunction(message: string): void
101 | }
102 | }
103 |
104 | declare module 'vuex/types/index' {
105 | // this.$myInjectedFunction inside Vuex stores
106 | interface Store {
107 | $myInjectedFunction(message: string): void
108 | }
109 | }
110 |
111 | const myPlugin: Plugin = (context, inject) => {
112 | inject('myInjectedFunction', (message: string) => console.log(message))
113 | }
114 |
115 | export default myPlugin
116 | ```
117 |
118 | ### Uso
119 |
120 | ```html
121 |
133 | ```
134 |
135 |
136 |
137 | Por favor, nota que el `inject` no inyecta en el `context` sino en `context.app`.
138 |
139 |
140 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server Middlewares (Tiempo de Ejecución)
3 | position: 28
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // Usa req, res, next
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/es/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Store
3 | position: 25
4 | description: 'Soporte de Typescript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | Existen varias formas diferentes de escribir y acceder al store en un proyecto de Nuxt usando Typescript.
9 |
10 | ## Class-based
11 |
12 | ### `vuex-module-decorators`
13 |
14 | Uno de los enfoques más popular es [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) - ver la [guía](https://championswimmer.in/vuex-module-decorators/).
15 |
16 |
17 | Para usar con Nuxt, existen pocos puntos claves:
18 |
19 | 1. Tus modulos deben ser decorados con `stateFactory: true`, por ejemplo:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. Si usted quiere acceder al store sin iniciarlo en cada componente, usted debe crear un [plugin inicializador](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs), por ejemplo:
44 | ```ts{}[store/index.ts]
45 | import { Store } from 'vuex'
46 | import { initialiseStores } from '~/utils/store-accessor'
47 |
48 | const initializer = (store: Store) => initialiseStores(store)
49 |
50 | export const plugins = [initializer]
51 | export * from '~/utils/store-accessor'
52 | ```
53 |
54 | 3. Si usted quiere acceder a la instancia app de Nuxt, usted debe hacer algo similar con un plugin, por ejemplo:
55 | ```ts{}[plugins/axios-accessor.ts]
56 | import { Plugin } from '@nuxt/types'
57 | import { initializeAxios } from '~/utils/api'
58 |
59 | const accessor: Plugin = ({ $axios }) => {
60 | initializeAxios($axios)
61 | }
62 |
63 | export default accessor
64 | ```
65 |
66 | ```ts{}[utils/api.ts]
67 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
68 |
69 | let $axios: NuxtAxiosInstance
70 |
71 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
72 | $axios = axiosInstance
73 | }
74 |
75 | export { $axios }
76 | ```
77 |
78 | ```ts{}[store/users.ts]
79 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
80 | import { $axios } from '~/utils/api'
81 | import { User } from '~/types'
82 |
83 | @Module({
84 | name: 'users',
85 | stateFactory: true,
86 | namespaced: true,
87 | })
88 | class UserModule extends VuexModule {
89 | users: User[] = []
90 |
91 | @Mutation
92 | setUsers(users: User[]) {
93 | this.users = users
94 | }
95 |
96 | @Action
97 | async getUsers() {
98 | const users = $axios.$get('/users')
99 | this.setUsers(users)
100 | }
101 | }
102 | ```
103 |
104 | ### `vuex-class-component`
105 |
106 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) es un enfoque basado en clases muy prometedor para el store de Nuxt, y la sintaxis es muy similar a `vuex-module-decorators`.Acaba de lanzar una nueva API, aunque todavía no es totalmente compatible con Nuxt. La solución alternativa es definir módulos con un decorador:
107 |
108 | ```ts
109 | @Module({ namespacedPath: 'foo' })
110 | export default class extends VuexModule {}
111 | ```
112 |
113 | Ver [este reporte](https://github.com/michaelolof/vuex-class-component/issues/43) para visualizar el estado actual de los problemas de compatibilidad con Nuxt.
114 |
115 | ## Vanilla
116 |
117 | ### Basico
118 |
119 | Vuex suministra tipos muy básicos para usar con la tienda. Puede usarlos para ayudar a definir su store. Por ejemplo:
120 |
121 | ```ts{}[store/index.ts]
122 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
123 |
124 | export const state = () => ({
125 | things: [] as string[],
126 | name: 'Me',
127 | })
128 |
129 | export type RootState = ReturnType
130 |
131 | export const getters: GetterTree = {
132 | name: state => state.name,
133 | }
134 |
135 | export const mutations: MutationTree = {
136 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
137 | }
138 |
139 | export const actions: ActionTree = {
140 | fetchThings({ commit }) {
141 | const things = this.$axios.$get('/things')
142 | console.log(things)
143 | commit('CHANGE_NAME', 'New name')
144 | },
145 | }
146 | ```
147 |
148 | Usted deberia hacer exactamente lo mismo para un modulo. Por ejemplo:
149 |
150 | `~/store/anotherModule.ts`:
151 | ```ts
152 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
153 | import { RootState } from '~/store'
154 |
155 | export const state = () => ({
156 | more: 3,
157 | })
158 |
159 | export type AnotherModuleState = ReturnType
160 |
161 | export const getters: GetterTree = {
162 | evenMore: state => state.more + 5,
163 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
164 | }
165 |
166 | export const actions: ActionTree = {
167 | printRootState({ rootState }) {
168 | console.log('accessing rootState:', rootState.name)
169 | },
170 | }
171 | ```
172 |
173 | ### Accediendo al store
174 |
175 | #### `nuxt-typed-vuex`
176 |
177 | Vuex no provee tipos utiles para acceder al store desde tu app. `this.$store` todavia esta sin tipos en una app de Nuxt.
178 |
179 | Aqui esta un nuevo proyecto, [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) - y una [guia](https://nuxt-typed-vuex.danielcroe.com/) - que tiene como objetivo remediar eso: proporcionar un acceso fuertemente tipado para un store de Nuxt.
180 |
181 | #### Hazlo a tu manera
182 |
183 | Alternativamente, usted puede proveer sus propios tipos como un punto de uso.
184 |
185 | ```ts{}[components/MyComponent.vue]
186 |
13 | ```
14 |
15 | ## Template
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | [@vue/composition-api](https://github.com/vuejs/composition-api) プラグインを使っています。
31 |
32 |
33 |
34 | **Plugin のインストール**
35 |
36 | ```js{}[plugins/composition-api.js]
37 | import Vue from 'vue'
38 | import VueCompositionApi from '@vue/composition-api'
39 |
40 | Vue.use(VueCompositionApi)
41 | ```
42 |
43 | ```js{}[nuxt.config.js]
44 | export default {
45 | plugins: ['@/plugins/composition-api']
46 | }
47 | ```
48 |
49 | このプラグインの登録は、コンポーネントで `setup` 機能を使うために必要です。
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator) から [vue-class-component](https://github.com/vuejs/vue-class-component) を使用しています。
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 設定(ランタイム)
3 | position: 26
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // 自動補完と型判定による設定の定義
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: ミドルウェア
3 | position: 23
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // context を使用します
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: モジュール(ランタイム)
3 | position: 27
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // this、this.options、this.nuxt を使用します
19 | // moduleOptions を使用します
20 | }
21 |
22 | export default myModule
23 |
24 | // モジュールを npm パッケージとして公開する場合は必須
25 | // export const meta = require('./package.json')
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: プラグイン
3 | position: 24
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ## I. Vue インスタンスにインジェクトする
9 |
10 | ### Plugin
11 |
12 | ```ts
13 | import Vue from 'vue'
14 |
15 | declare module 'vue/types/vue' {
16 | interface Vue {
17 | $myInjectedFunction(message: string): void
18 | }
19 | }
20 |
21 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
22 | ```
23 |
24 | ### 使用方法
25 |
26 | ```html
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 | ```
44 |
45 | ## II. コンテキストにインジェクトする
46 |
47 | ### Plugin
48 |
49 | ```ts
50 | import { Plugin } from '@nuxt/types'
51 |
52 | declare module '@nuxt/types' {
53 | interface Context {
54 | $myInjectedFunction(message: string): void
55 | }
56 | }
57 |
58 | const myPlugin: Plugin = (context) => {
59 | context.$myInjectedFunction = (message: string) => console.log(message)
60 | }
61 |
62 | export default myPlugin
63 | ```
64 |
65 | ### 使用方法
66 |
67 | ```html
68 |
77 | ```
78 |
79 | ## III. 複合インジェクト
80 |
81 | ### Plugin
82 |
83 | ```ts
84 | import { Plugin } from '@nuxt/types'
85 |
86 | declare module 'vue/types/vue' {
87 | interface Vue {
88 | $myInjectedFunction(message: string): void
89 | }
90 | }
91 |
92 | declare module '@nuxt/types' {
93 | interface NuxtAppOptions {
94 | $myInjectedFunction(message: string): void
95 | }
96 | }
97 |
98 | declare module 'vuex/types/index' {
99 | interface Store {
100 | $myInjectedFunction(message: string): void
101 | }
102 | }
103 |
104 | const myPlugin: Plugin = (context, inject) => {
105 | inject('myInjectedFunction', (message: string) => console.log(message))
106 | }
107 |
108 | export default myPlugin
109 | ```
110 |
111 | ### 使用方法
112 |
113 | ```html
114 |
126 | ```
127 |
128 |
129 |
130 | `inject` は `context` ではなく `context.app` にインジェクトされることに注意してください。
131 |
132 |
133 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server Middlewares(ランタイム)
3 | position: 28
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // req, res, next を使用
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/ja/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: ストア
3 | position: 25
4 | description: 'Nuxt.js 向け TypeScript サポート'
5 | category: 'Cookbook'
6 | ---
7 |
8 | TypeScript を使用している Nuxt プロジェクトでは、ストアにアクセスしたり、書き込んだりするためにさまざまなオプションがあります。
9 |
10 | ## クラスベース
11 |
12 | ### `vuex-module-decorators`
13 |
14 | 最も人気のあるアプローチの1つは [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) です。- [ガイド](https://championswimmer.in/vuex-module-decorators/)を参照してください。
15 |
16 |
17 | Nuxt で使用するために重要な条件がいくつかあります:
18 |
19 | 1. モジュールは `stateFactory: true` で装飾する必要があるため、以下のようにします:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. 各コンポーネントで初期化せずにストアにアクセスした場合は、[initialiser plugin](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs) を使用してアクセスすることができます。例:
44 | ```ts{}[store/index.ts]
45 | import { Store } from 'vuex'
46 | import { initialiseStores } from '~/utils/store-accessor'
47 |
48 | const initializer = (store: Store) => initialiseStores(store)
49 |
50 | export const plugins = [initializer]
51 | export * from '~/utils/store-accessor'
52 | ```
53 |
54 | 3. Nuxt アプリケーションインスタンスにアクセスしたい場合は、プラグインと同様に設定を行う必要があります。例:
55 | ```ts{}[plugins/axios-accessor.ts]
56 | import { Plugin } from '@nuxt/types'
57 | import { initializeAxios } from '~/utils/api'
58 |
59 | const accessor: Plugin = ({ $axios }) => {
60 | initializeAxios($axios)
61 | }
62 |
63 | export default accessor
64 | ```
65 |
66 | プラグインを忘れずに `nuxt.config.js` ファイルに追加してください。
67 |
68 | ```ts{}[utils/api.ts]
69 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
70 |
71 | let $axios: NuxtAxiosInstance
72 |
73 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
74 | $axios = axiosInstance
75 | }
76 |
77 | export { $axios }
78 | ```
79 |
80 | ```ts{}[store/users.ts]
81 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
82 | import { $axios } from '~/utils/api'
83 | import { User } from '~/types'
84 |
85 | @Module({
86 | name: 'users',
87 | stateFactory: true,
88 | namespaced: true,
89 | })
90 | class UserModule extends VuexModule {
91 | users: User[] = []
92 |
93 | @Mutation
94 | setUsers(users: User[]) {
95 | this.users = users
96 | }
97 |
98 | @Action
99 | async getUsers() {
100 | const users = $axios.$get('/users')
101 | this.setUsers(users)
102 | }
103 | }
104 | ```
105 |
106 | ### `vuex-class-component`
107 |
108 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) は Nuxt ストアに対する非常に有望なクラスベースのアプローチであり、シンタックスは `vuex-module-decorators` にとても似ています。新しい API をリリースしましたが、Nuxt との互換性は完全ではありません。回避策はデコレーターでモジュールを定義することです。
109 |
110 | ```ts
111 | @Module({ namespacedPath: 'foo' })
112 | export default class extends VuexModule {}
113 | ```
114 |
115 | Nuxt との互換性問題の現在の状態については、[このイシュー](https://github.com/michaelolof/vuex-class-component/issues/43)を参照してください。
116 |
117 | ## Vanilla
118 |
119 | ### 基本的なタイピング
120 |
121 | Vuex はストアを使用するために非常に基本的な型を提供しています。これらを使用してストアを定義することができます。例:
122 |
123 | ```ts{}[store/index.ts]
124 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
125 |
126 | export const state = () => ({
127 | things: [] as string[],
128 | name: 'Me',
129 | })
130 |
131 | export type RootState = ReturnType
132 |
133 | export const getters: GetterTree = {
134 | name: state => state.name,
135 | }
136 |
137 | export const mutations: MutationTree = {
138 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
139 | }
140 |
141 | export const actions: ActionTree = {
142 | fetchThings({ commit }) {
143 | const things = this.$axios.$get('/things')
144 | console.log(things)
145 | commit('CHANGE_NAME', 'New name')
146 | },
147 | }
148 | ```
149 |
150 | モジュールに対しても同様のことができます。例:
151 |
152 | `~/store/anotherModule.ts`:
153 | ```ts
154 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
155 | import { RootState } from '~/store'
156 |
157 | export const state = () => ({
158 | more: 3,
159 | })
160 |
161 | export type AnotherModuleState = ReturnType
162 |
163 | export const getters: GetterTree = {
164 | evenMore: state => state.more + 5,
165 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
166 | }
167 |
168 | export const actions: ActionTree = {
169 | printRootState({ rootState }) {
170 | console.log('accessing rootState:', rootState.name)
171 | },
172 | }
173 | ```
174 |
175 | ### ストアへのアクセス
176 |
177 | #### `nuxt-typed-vuex`
178 |
179 | Vuex はアプリケーションからストアへアクセスするための便利な型を提供していません。`this.$store` は Nuxt アプリケーションで型指定されていないままです。
180 |
181 | [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) という新しいプロジェクトがあり([ガイド](https://nuxt-typed-vuex.danielcroe.com/))、このプロジェクトは素の Nuxt ストアに強く型付けされたアクセサーを提供することで上述の件を改善することを目的としています。
182 |
183 | #### 自前のものを使う
184 |
185 | もう1つの方法としては、使用時に自前の型を提供することができます。
186 |
187 | ```ts{}[components/MyComponent.vue]
188 |
13 | ```
14 |
15 | ## Modelo
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 | Usando o plugin [@vue/composition-api](https://github.com/vuejs/composition-api)
29 |
30 |
31 |
32 | **Instalação do plugin**
33 |
34 | ```js{}[plugins/composition-api.js]
35 | import Vue from 'vue'
36 | import VueCompositionApi from '@vue/composition-api'
37 |
38 | Vue.use(VueCompositionApi)
39 | ```
40 |
41 | ```js{}[nuxt.config.js]
42 | export default {
43 | plugins: ['@/plugins/composition-api']
44 | }
45 | ```
46 |
47 | Esse registo do plugin é obrigatório para fazer a função `setup` funcionar em componentes.
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 | Usando [vue-class-component](https://github.com/vuejs/vue-class-component) através do [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator)
58 |
59 |
60 |
61 |
62 |
63 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Configuração (Tempo de execução)
3 | position: 26
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // Defina sua configuração com preenchimento automático e verificação de tipo
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Middlewares
3 | position: 23
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // Use o contexto
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Módulos (Tempo de execução)
3 | position: 27
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // Use this, this.options, this.nuxt
19 | // Use moduleOptions
20 | }
21 |
22 | export default myModule
23 |
24 | // NECESSÁRIO se publicar o módulo como um pacote npm
25 | // export const meta = require('./package.json')
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Plugins
3 | position: 24
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ## I. Injetar em instâncias do Vue
9 |
10 | ### Plugin
11 |
12 | ```ts
13 | import Vue from 'vue'
14 |
15 | declare module 'vue/types/vue' {
16 | interface Vue {
17 | $myInjectedFunction(message: string): void
18 | }
19 | }
20 |
21 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
22 | ```
23 |
24 | ### Uso
25 |
26 | ```html
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 | ```
44 |
45 | ## II. Injetar no contexto
46 |
47 | ### Plugin
48 |
49 | ```ts
50 | import { Plugin } from '@nuxt/types'
51 |
52 | declare module '@nuxt/types' {
53 | interface Context {
54 | $myInjectedFunction(message: string): void
55 | }
56 | }
57 |
58 | const myPlugin: Plugin = (context) => {
59 | context.$myInjectedFunction = (message: string) => console.log(message)
60 | }
61 |
62 | export default myPlugin
63 | ```
64 |
65 | ### Uso
66 |
67 | ```html
68 |
77 | ```
78 |
79 | ## III. Injeção combinada
80 |
81 | ### Plugin
82 |
83 | ```ts
84 | import { Plugin } from '@nuxt/types'
85 |
86 | declare module 'vue/types/vue' {
87 | interface Vue {
88 | $myInjectedFunction(message: string): void
89 | }
90 | }
91 |
92 | declare module '@nuxt/types' {
93 | // nuxtContext.app.$myInjectedFunction dentro de asyncData, fetch, plugins, middleware, nuxtServerInit
94 | interface NuxtAppOptions {
95 | $myInjectedFunction(message: string): void
96 | }
97 | // nuxtContext.$myInjectedFunction
98 | interface Context {
99 | $myInjectedFunction(message: string): void
100 | }
101 | }
102 |
103 | declare module 'vuex/types/index' {
104 | // this.$myInjectedFunction dentro de stores Vuex
105 | interface Store {
106 | $myInjectedFunction(message: string): void
107 | }
108 | }
109 |
110 | const myPlugin: Plugin = (context, inject) => {
111 | inject('myInjectedFunction', (message: string) => console.log(message))
112 | }
113 |
114 | export default myPlugin
115 | ```
116 |
117 | ### Uso
118 |
119 | ```html
120 |
132 | ```
133 |
134 |
135 |
136 | Por favor note que o `inject` não injeta no` context`, mas no `context.app`.
137 |
138 |
139 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Server Middlewares (Tempo de execução)
3 | position: 28
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // Use req, res, next
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/pt/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Store
3 | position: 25
4 | description: 'Suporte de TypeScript para Nuxt.js'
5 | category: 'Cookbook'
6 | ---
7 |
8 | Existem várias opções diferentes para escrever e acessar o store em um projeto Nuxt usando o TypeScript.
9 |
10 | ## Baseado em classe
11 |
12 | ### `vuex-module-decorators`
13 |
14 | Uma das abordagens mais populares é o [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) - veja o [guia](https://championswimmer.in/vuex-module-decorators/).
15 |
16 |
17 | Para uso com o Nuxt, existem poucas condições principais:
18 |
19 | 1. Seus módulos devem ser decorados com `stateFactory: true`, por exemplo:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. Se você quiser acessar o store sem inicializá-lo em cada componente, poderá fazê-lo usando um [plugin inicializador](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs), por exemplo:
44 | ```ts{}[store/index.ts]
45 | import { Store } from 'vuex'
46 | import { initialiseStores } from '~/utils/store-accessor'
47 |
48 | const initializer = (store: Store) => initialiseStores(store)
49 |
50 | export const plugins = [initializer]
51 | export * from '~/utils/store-accessor'
52 | ```
53 |
54 | 3. Se você deseja acessar a instância do aplicativo Nuxt, precisará fazer algo semelhante com um plug-in, por exemplo:
55 | ```ts{}[plugins/axios-accessor.ts]
56 | import { Plugin } from '@nuxt/types'
57 | import { initializeAxios } from '~/utils/api'
58 |
59 | const accessor: Plugin = ({ $axios }) => {
60 | initializeAxios($axios)
61 | }
62 |
63 | export default accessor
64 | ```
65 |
66 | Não se esqueça de adicionar o plugin para seu arquivo `nuxt.config.js`.
67 |
68 | ```ts{}[utils/api.ts]
69 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
70 |
71 | let $axios: NuxtAxiosInstance
72 |
73 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
74 | $axios = axiosInstance
75 | }
76 |
77 | export { $axios }
78 | ```
79 |
80 | ```ts{}[store/users.ts]
81 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
82 | import { $axios } from '~/utils/api'
83 | import { User } from '~/types'
84 |
85 | @Module({
86 | name: 'users',
87 | stateFactory: true,
88 | namespaced: true,
89 | })
90 | class UserModule extends VuexModule {
91 | users: User[] = []
92 |
93 | @Mutation
94 | setUsers(users: User[]) {
95 | this.users = users
96 | }
97 |
98 | @Action
99 | async getUsers() {
100 | const users = await $axios.$get('/users')
101 | this.setUsers(users)
102 | }
103 | }
104 | ```
105 |
106 | ### `vuex-class-component`
107 |
108 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) é uma abordagem baseada em classe muito promissora para o Nuxt store, e a sintaxe é muito semelhante ao `vuex-module-decorators`. Ele acaba de lançar uma nova API, embora ainda não seja compatível totalmente com o Nuxt. A solução alternativa é definir módulos com um decorador:
109 |
110 | ```ts
111 | @Module({ namespacedPath: 'foo' })
112 | export default class extends VuexModule {}
113 | ```
114 |
115 | Consulte [esse issue](https://github.com/michaelolof/vuex-class-component/issues/43) para obter o status atual do problema de compatibilidade com o Nuxt.
116 |
117 | ## Vanilla
118 |
119 | ### Tipagem básica
120 |
121 | O Vuex fornece tipos muito básicos para uso no store. Você pode usá-los para ajudar a definir seu store. Por exemplo:
122 |
123 | ```ts{}[store/index.ts]
124 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
125 |
126 | export const state = () => ({
127 | things: [] as string[],
128 | name: 'Me',
129 | })
130 |
131 | export type RootState = ReturnType
132 |
133 | export const getters: GetterTree = {
134 | name: state => state.name,
135 | }
136 |
137 | export const mutations: MutationTree = {
138 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
139 | }
140 |
141 | export const actions: ActionTree = {
142 | fetchThings({ commit }) {
143 | const things = this.$axios.$get('/things')
144 | console.log(things)
145 | commit('CHANGE_NAME', 'Novo nome')
146 | },
147 | }
148 | ```
149 |
150 | Você faria exatamente o mesmo para um módulo. Por exemplo:
151 |
152 | `~/store/anotherModule.ts`:
153 | ```ts
154 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
155 | import { RootState } from '~/store'
156 |
157 | export const state = () => ({
158 | more: 3,
159 | })
160 |
161 | export type AnotherModuleState = ReturnType
162 |
163 | export const getters: GetterTree = {
164 | evenMore: state => state.more + 5,
165 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
166 | }
167 |
168 | export const actions: ActionTree = {
169 | printRootState({ rootState }) {
170 | console.log('accessing rootState:', rootState.name)
171 | },
172 | }
173 | ```
174 |
175 | ### Acessando o store
176 |
177 | #### `nuxt-typed-vuex`
178 |
179 |
180 | O Vuex não fornece tipos úteis para acessar a store a partir da sua aplicação. `this.$store` permanece sem tipo em um aplicação Nuxt.
181 |
182 | Há um novo projeto, o [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) - e o [guia](https://nuxt-typed-vuex.danielcroe.com/) - que visa remediar isso - fornecendo um acessador fortemente tipado para uma store do Nuxt vanilla.
183 |
184 |
185 | #### Traga o seu próprio
186 |
187 | Alternativamente, você pode fornecer seus próprios tipos no ponto de uso.
188 |
189 | ```ts{}[components/MyComponent.vue]
190 |
13 | ```
14 |
15 | ## 模板
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 使用 [@vue/composition-api](https://github.com/vuejs/composition-api) 插件
31 |
32 |
33 |
34 | **插件安装方法**
35 |
36 | ```js{}[plugins/composition-api.js]
37 | import Vue from 'vue'
38 | import VueCompositionApi from '@vue/composition-api'
39 |
40 | Vue.use(VueCompositionApi)
41 | ```
42 |
43 | ```js{}[nuxt.config.js]
44 | export default {
45 | plugins: ['@/plugins/composition-api']
46 | }
47 | ```
48 |
49 | 此插件注册后,`setup` 才能在组件中产生作用。
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 通过 [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator) 来使用 [vue-class-component](https://github.com/vuejs/vue-class-component)
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 配置文件 (运行时)
3 | position: 26
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // 在编写配置文件时,使用自动完成以及类型检查
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 中间件
3 | position: 23
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // 使用 context
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模块 (运行时)
3 | position: 27
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // 使用 this, this.options, this.nuxt
19 | // 使用 moduleOptions
20 | }
21 |
22 | export default myModule
23 |
24 | // 如果要将这个模块发布成 npm 包,必须使用
25 | // export const meta = require('./package.json')
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 插件
3 | position: 24
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ## I. 注入到 Vue 实例
9 |
10 | ### 插件
11 |
12 | ```ts
13 | declare module 'vue/types/vue' {
14 | interface Vue {
15 | $myInjectedFunction(message: string): void
16 | }
17 | }
18 |
19 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
20 | ```
21 |
22 | ### 使用方法
23 |
24 | ```html
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
41 | ```
42 |
43 | ## II. 注入到 context
44 |
45 | ### 插件
46 |
47 | ```ts
48 | import { Plugin } from '@nuxt/types'
49 |
50 | declare module '@nuxt/types' {
51 | interface Context {
52 | $myInjectedFunction(message: string): void
53 | }
54 | }
55 |
56 | const myPlugin: Plugin = (context) => {
57 | context.$myInjectedFunction = (message: string) => console.log(message)
58 | }
59 |
60 | export default myPlugin
61 | ```
62 |
63 | ### 使用方法
64 |
65 | ```html
66 |
75 | ```
76 |
77 | ## III. 两者一起注入
78 |
79 | ### 插件
80 |
81 | ```ts
82 | import { Plugin } from '@nuxt/types'
83 |
84 | declare module 'vue/types/vue' {
85 | interface Vue {
86 | $myInjectedFunction(message: string): void
87 | }
88 | }
89 |
90 | declare module '@nuxt/types' {
91 | interface NuxtAppOptions {
92 | $myInjectedFunction(message: string): void
93 | }
94 | }
95 |
96 | declare module 'vuex/types/index' {
97 | interface Store {
98 | $myInjectedFunction(message: string): void
99 | }
100 | }
101 |
102 | const myPlugin: Plugin = (context, inject) => {
103 | inject('myInjectedFunction', (message: string) => console.log(message))
104 | }
105 |
106 | export default myPlugin
107 | ```
108 |
109 | ### 使用方法
110 |
111 | ```html
112 |
124 | ```
125 |
126 |
127 |
128 | 请注意, `inject` 注入到 `context.app` ,而不是 `context` 。
129 |
130 |
131 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 服务器渲染中间件 (运行时)
3 | position: 28
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // 使用 req, res, next
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hans/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Store
3 | position: 25
4 | description: 'Nuxt.js 的 Typescript 支持'
5 | category: '更多使用方式'
6 | ---
7 |
8 | 在 Nuxt 项目中以 TypeScript 使用 store 的方法有多种。
9 |
10 | ## 基于类的方式
11 |
12 | ### `vuex-module-decorators`
13 |
14 | 最受欢迎的使用方式是 [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) - 查看 [指南](https://championswimmer.in/vuex-module-decorators/).
15 |
16 |
17 | 在与 Nuxt 一起使用时,有几个主要的限制条件:
18 |
19 | 1. 你的模块必须以 `stateFactory: true` 装饰器装饰,例如:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. 如果你想要不在每个组件中初始化,就能访问 store,你可以使用
44 | [initialiser plugin](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs), 例如:
45 | ```ts{}[store/index.ts]
46 | import { Store } from 'vuex'
47 | import { initialiseStores } from '~/utils/store-accessor'
48 |
49 | const initializer = (store: Store) => initialiseStores(store)
50 |
51 | export const plugins = [initializer]
52 | export * from '~/utils/store-accessor'
53 | ```
54 |
55 | 3. 如果你想访问 Nuxt app 实例,你需要使用插件,例如:
56 | ```ts{}[plugins/axios-accessor.ts]
57 | import { Plugin } from '@nuxt/types'
58 | import { initializeAxios } from '~/utils/api'
59 |
60 | const accessor: Plugin = ({ $axios }) => {
61 | initializeAxios($axios)
62 | }
63 |
64 | export default accessor
65 | ```
66 |
67 | ```ts{}[utils/api.ts]
68 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
69 |
70 | let $axios: NuxtAxiosInstance
71 |
72 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
73 | $axios = axiosInstance
74 | }
75 |
76 | export { $axios }
77 | ```
78 |
79 | ```ts{}[store/users.ts]
80 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
81 | import { $axios } from '~/utils/api'
82 | import { User } from '~/types'
83 |
84 | @Module({
85 | name: 'users',
86 | stateFactory: true,
87 | namespaced: true,
88 | })
89 | class UserModule extends VuexModule {
90 | users: User[] = []
91 |
92 | @Mutation
93 | setUsers(users: User[]) {
94 | this.users = users
95 | }
96 |
97 | @Action
98 | async getUsers() {
99 | const users = $axios.$get('/users')
100 | this.setUsers(users)
101 | }
102 | }
103 | ```
104 |
105 | ### `vuex-class-component`
106 |
107 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) 是一个很有前景的、基于类的 Nuxt Store,其语法类似于 `vuex-module-decorators`。不久前它转而使用新的 API,与 Nuxt 并不完全兼容。暂时的解决方案是使用装饰器定义 Vuex 模块:
108 |
109 | ```ts
110 | @Module({ namespacedPath: 'foo' })
111 | export default class extends VuexModule {}
112 | ```
113 |
114 | 查看 [这个问题](https://github.com/michaelolof/vuex-class-component/issues/43) 来追踪目前在 Nuxt 遇到的兼容性问题状态。
115 |
116 |
117 |
118 | ## 原生 Vuex
119 |
120 | ### 基本类型
121 |
122 | 当你在使用 store 时,Vuex 提供了非常基本的类型。你可以使用它们为你的 store 定义提供帮助。例如:
123 |
124 | ```ts{}[store/index.ts]
125 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
126 |
127 | export const state = () => ({
128 | things: [] as string[],
129 | name: 'Me',
130 | })
131 |
132 | export type RootState = ReturnType
133 |
134 | export const getters: GetterTree = {
135 | name: state => state.name,
136 | }
137 |
138 | export const mutations: MutationTree = {
139 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
140 | }
141 |
142 | export const actions: ActionTree = {
143 | fetchThings({ commit }) {
144 | const things = this.$axios.$get('/things')
145 | console.log(things)
146 | commit('CHANGE_NAME', 'New name')
147 | },
148 | }
149 | ```
150 |
151 | 在模块中,你也会使用类似的方法。例如:
152 |
153 | `~/store/anotherModule.ts`:
154 | ```ts
155 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
156 | import { RootState } from '~/store'
157 |
158 | export const state = () => ({
159 | more: 3,
160 | })
161 |
162 | export type AnotherModuleState = ReturnType
163 |
164 | export const getters: GetterTree = {
165 | evenMore: state => state.more + 5,
166 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
167 | }
168 |
169 | export const actions: ActionTree = {
170 | printRootState({ rootState }) {
171 | console.log('accessing rootState:', rootState.name)
172 | },
173 | }
174 | ```
175 |
176 | ### 访问 store
177 |
178 | #### `nuxt-typed-vuex`
179 |
180 | 当你从 Nuxt app 中访问时,Vuex 并不提供有用的类型信息,其结果是 `this.$store` 缺少类型提示。
181 |
182 | 有一个新项目 [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) - 和 [指南](https://nuxt-typed-vuex.danielcroe.com/) - 皆在试图为原生 Nuxt store 访问提供强类型标注。
183 |
184 | #### 自己来
185 |
186 | 或者,你也可以自己提供类型信息。
187 |
188 | ```ts{}[components/MyComponent.vue]
189 |
13 | ```
14 |
15 | ## 模板
16 |
17 |
18 |
19 | ## Script
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 | 使用 [@vue/composition-api](https://github.com/vuejs/composition-api) 擴充元件
31 |
32 |
33 |
34 | **Plugin 安裝方法**
35 |
36 | ```js{}[plugins/composition-api.js]
37 | import Vue from 'vue'
38 | import VueCompositionApi from '@vue/composition-api'
39 |
40 | Vue.use(VueCompositionApi)
41 | ```
42 |
43 | ```js{}[nuxt.config.js]
44 | export default {
45 | plugins: ['@/plugins/composition-api']
46 | }
47 | ```
48 |
49 | 此 擴充元件 註冊後才能讓 `setup` 在元件中產生作用。
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 | 透過 [vue-property-decorator](https://github.com/kaorun343/vue-property-decorator) 來使用 [vue-class-component](https://github.com/vuejs/vue-class-component)
60 |
61 |
62 |
63 |
64 |
65 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/configuration.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 設定 (Runtime)
3 | position: 26
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { NuxtConfig } from '@nuxt/types'
10 |
11 | const config: NuxtConfig = {
12 | // 透過 自動完成 以及 型別檢查 定義設定
13 | }
14 |
15 | export default config
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 中介層
3 | position: 23
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { Middleware } from '@nuxt/types'
10 |
11 | const myMiddleware: Middleware = (context) => {
12 | // 使用 context
13 | }
14 |
15 | export default myMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/modules.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 模組 (Runtime)
3 | position: 27
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { Module } from '@nuxt/types'
10 |
11 | interface Options {
12 | a: boolean
13 | b: number
14 | c: string
15 | }
16 |
17 | const myModule: Module = function (moduleOptions) {
18 | // 使用 this, this.options, this.nuxt
19 | // 使用 moduleOptions
20 | }
21 |
22 | export default myModule
23 |
24 | // 如果要將這個模組發佈成 npm 套件時,必要使用
25 | // export const meta = require('./package.json')
26 | ```
27 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/plugins.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 擴充元件
3 | position: 24
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ## I. 注入到 Vue 實例
9 |
10 | ### Plugin
11 |
12 | ```ts
13 | import Vue from 'vue'
14 |
15 | declare module 'vue/types/vue' {
16 | interface Vue {
17 | $myInjectedFunction(message: string): void
18 | }
19 | }
20 |
21 | Vue.prototype.$myInjectedFunction = (message: string) => console.log(message)
22 | ```
23 |
24 | ### 使用方法
25 |
26 | ```html
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
43 | ```
44 |
45 | ## II. 注入到 context
46 |
47 | ### Plugin
48 |
49 | ```ts
50 | import { Plugin } from '@nuxt/types'
51 |
52 | declare module '@nuxt/types' {
53 | interface Context {
54 | $myInjectedFunction(message: string): void
55 | }
56 | }
57 |
58 | const myPlugin: Plugin = (context) => {
59 | context.$myInjectedFunction = (message: string) => console.log(message)
60 | }
61 |
62 | export default myPlugin
63 | ```
64 |
65 | ### 使用方法
66 |
67 | ```html
68 |
77 | ```
78 |
79 | ## III. 兩者一起注入
80 |
81 | ### Plugin
82 |
83 | ```ts
84 | import { Plugin } from '@nuxt/types'
85 |
86 | declare module 'vue/types/vue' {
87 | interface Vue {
88 | $myInjectedFunction(message: string): void
89 | }
90 | }
91 |
92 | declare module '@nuxt/types' {
93 | interface NuxtAppOptions {
94 | $myInjectedFunction(message: string): void
95 | }
96 | }
97 |
98 | declare module 'vuex/types/index' {
99 | interface Store {
100 | $myInjectedFunction(message: string): void
101 | }
102 | }
103 |
104 | const myPlugin: Plugin = (context, inject) => {
105 | inject('myInjectedFunction', (message: string) => console.log(message))
106 | }
107 |
108 | export default myPlugin
109 | ```
110 |
111 | ### 使用方法
112 |
113 | ```html
114 |
126 | ```
127 |
128 |
129 |
130 | 請注意, `inject` 是在 `context.app` 中注入,並不會存在於 `context` 中。
131 |
132 |
133 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/server-middlewares.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: 伺服器渲染中介層 (Runtime)
3 | position: 28
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | ```ts
9 | import { ServerMiddleware } from '@nuxt/types'
10 |
11 | const myServerMiddleware: ServerMiddleware = function (req, res, next) {
12 | // 使用 req, res, next
13 | }
14 |
15 | export default myServerMiddleware
16 | ```
17 |
--------------------------------------------------------------------------------
/docs/content/zh-Hant/cookbook/store.md:
--------------------------------------------------------------------------------
1 | ---
2 | title: Store
3 | position: 25
4 | description: 'Nuxt.js 的 Typescript 支援'
5 | category: '更多使用方式'
6 | ---
7 |
8 | 在 Nuxt 專案中以 TypeScript 使用 store 的方法有很多種。
9 |
10 | ## Class-based
11 |
12 | ### `vuex-module-decorators`
13 |
14 | 最受歡迎的使用方式是 [vuex-module-decorators](https://github.com/championswimmer/vuex-module-decorators) - 查看 [guide](https://championswimmer.in/vuex-module-decorators/).
15 |
16 |
17 | 為了與 Nuxt 一起使用,有幾個主要的限制條件:
18 |
19 | 1. 你的模組必須和 `stateFactory: true` 一起使用,例如:
20 |
21 | ```ts{}[store/mymodule.ts]
22 | import { Module, VuexModule, Mutation } from 'vuex-module-decorators'
23 |
24 | @Module({
25 | name: 'mymodule',
26 | stateFactory: true,
27 | namespaced: true,
28 | })
29 | class MyModule extends VuexModule {
30 | wheels = 2
31 |
32 | @Mutation
33 | incrWheels(extra) {
34 | this.wheels += extra
35 | }
36 |
37 | get axles() {
38 | return this.wheels / 2
39 | }
40 | }
41 | ```
42 |
43 | 2. 如果你不想要在每個元件中初始化並存取 store,你可以使用
44 | [initialiser plugin](https://github.com/championswimmer/vuex-module-decorators#accessing-modules-with-nuxtjs), 例如:
45 | ```ts{}[store/index.ts]
46 | import { Store } from 'vuex'
47 | import { initialiseStores } from '~/utils/store-accessor'
48 |
49 | const initializer = (store: Store) => initialiseStores(store)
50 |
51 | export const plugins = [initializer]
52 | export * from '~/utils/store-accessor'
53 | ```
54 |
55 | 3. 如果你想要存取 Nuxt app 實例,你會需要對 plugin 做類似的事,例如:
56 | ```ts{}[plugins/axios-accessor.ts]
57 | import { Plugin } from '@nuxt/types'
58 | import { initializeAxios } from '~/utils/api'
59 |
60 | const accessor: Plugin = ({ $axios }) => {
61 | initializeAxios($axios)
62 | }
63 |
64 | export default accessor
65 | ```
66 |
67 | ```ts{}[utils/api.ts]
68 | import { NuxtAxiosInstance } from '@nuxtjs/axios'
69 |
70 | let $axios: NuxtAxiosInstance
71 |
72 | export function initializeAxios(axiosInstance: NuxtAxiosInstance) {
73 | $axios = axiosInstance
74 | }
75 |
76 | export { $axios }
77 | ```
78 |
79 | ```ts{}[store/users.ts]
80 | import { Module, VuexModule, Action, Mutation } from 'vuex-module-decorators'
81 | import { $axios } from '~/utils/api'
82 | import { User } from '~/types'
83 |
84 | @Module({
85 | name: 'users',
86 | stateFactory: true,
87 | namespaced: true,
88 | })
89 | class UserModule extends VuexModule {
90 | users: User[] = []
91 |
92 | @Mutation
93 | setUsers(users: User[]) {
94 | this.users = users
95 | }
96 |
97 | @Action
98 | async getUsers() {
99 | const users = $axios.$get('/users')
100 | this.setUsers(users)
101 | }
102 | }
103 | ```
104 |
105 | ### `vuex-class-component`
106 |
107 | [`vuex-class-component`](https://github.com/michaelolof/vuex-class-component) 的語法相似於 `vuex-module-decorators`,是一個有望成為以 class 為基底的 Nuxt store。儘管他還沒有和 Nuxt 非常相容,但不久前發佈了新的 API,暫時的替代方案是使用模組的 decorator:
108 |
109 | ```ts
110 | @Module({ namespacedPath: 'foo' })
111 | export default class extends VuexModule {}
112 | ```
113 |
114 | 查看 [這個問題](https://github.com/michaelolof/vuex-class-component/issues/43) 來追蹤目前在 Nuxt 遇到的相容性問題狀態。
115 |
116 |
117 |
118 | ## 原生 Vanilla
119 |
120 | ### 基本型別
121 |
122 | 當你在使用 store 時,Vuex 提供了非常基本的型別。你可以使用他們幫助你定義你的 store。例如:
123 |
124 | ```ts{}[store/index.ts]
125 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
126 |
127 | export const state = () => ({
128 | things: [] as string[],
129 | name: 'Me',
130 | })
131 |
132 | export type RootState = ReturnType
133 |
134 | export const getters: GetterTree = {
135 | name: state => state.name,
136 | }
137 |
138 | export const mutations: MutationTree = {
139 | CHANGE_NAME: (state, newName: string) => (state.name = newName),
140 | }
141 |
142 | export const actions: ActionTree = {
143 | fetchThings({ commit }) {
144 | const things = this.$axios.$get('/things')
145 | console.log(things)
146 | commit('CHANGE_NAME', 'New name')
147 | },
148 | }
149 | ```
150 |
151 | 你也會在模組當中使用一模一樣的方法。例如:
152 |
153 | `~/store/anotherModule.ts`:
154 | ```ts
155 | import { GetterTree, ActionTree, MutationTree } from 'vuex'
156 | import { RootState } from '~/store'
157 |
158 | export const state = () => ({
159 | more: 3,
160 | })
161 |
162 | export type AnotherModuleState = ReturnType
163 |
164 | export const getters: GetterTree = {
165 | evenMore: state => state.more + 5,
166 | nameAndMore: (state, getters, rootState) => `${rootState.name}: ${state.more}`,
167 | }
168 |
169 | export const actions: ActionTree = {
170 | printRootState({ rootState }) {
171 | console.log('accessing rootState:', rootState.name)
172 | },
173 | }
174 | ```
175 |
176 | ### 存取 store
177 |
178 | #### `nuxt-typed-vuex`
179 |
180 | Vuex 並沒有在你的應用程式當中提供型別給你,在 Nuxt app 中,你會得到一個沒有任何型別的 `this.$store`。
181 |
182 | 有一個新項目 [`nuxt-typed-vuex`](https://github.com/danielroe/nuxt-typed-vuex) - 和 [guide](https://nuxt-typed-vuex.danielcroe.com/) - 皆在試圖解決這個問題。
183 |
184 | #### 自己來
185 |
186 | 或者你也可以使用自己提供的型別。
187 |
188 | ```ts{}[components/MyComponent.vue]
189 |
29 |
30 |
39 |
--------------------------------------------------------------------------------
/examples/class-api/basic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "experimentalDecorators": true,
13 | "allowJs": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "noEmit": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "~/*": [
20 | "./*"
21 | ],
22 | "@/*": [
23 | "./*"
24 | ]
25 | },
26 | "types": [
27 | "@nuxt/types"
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/class-api/minimal/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt TypeScript with Class API (minimal)
2 |
3 | https://typescript.nuxtjs.org/examples/class-api/minimal
4 |
--------------------------------------------------------------------------------
/examples/class-api/minimal/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | buildModules: ['@nuxt/typescript-build']
3 | }
4 |
--------------------------------------------------------------------------------
/examples/class-api/minimal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-class-api-minimal",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "nuxt": "latest",
7 | "vue-class-component": "latest",
8 | "vue-property-decorator": "latest"
9 | },
10 | "scripts": {
11 | "dev": "nuxt",
12 | "build": "nuxt build",
13 | "start": "nuxt start",
14 | "generate": "nuxt generate",
15 | "post-update": "yarn upgrade --latest"
16 | },
17 | "devDependencies": {
18 | "@nuxt/types": "latest",
19 | "@nuxt/typescript-build": "latest"
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/examples/class-api/minimal/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ message }}
4 |
5 |
6 |
7 |
15 |
--------------------------------------------------------------------------------
/examples/class-api/minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "experimentalDecorators": true,
13 | "allowJs": true,
14 | "sourceMap": true,
15 | "strict": true,
16 | "noEmit": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "~/*": [
20 | "./*"
21 | ],
22 | "@/*": [
23 | "./*"
24 | ]
25 | },
26 | "types": [
27 | "@nuxt/types"
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt TypeScript with Composition API (basic)
2 |
3 | https://typescript.nuxtjs.org/examples/composition-api/basic
4 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | buildModules: ['@nuxt/typescript-build'],
3 | plugins: ['~/plugins/composition-api']
4 | }
5 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-composition-api-basic",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "@vue/composition-api": "latest",
7 | "nuxt": "latest"
8 | },
9 | "scripts": {
10 | "dev": "nuxt",
11 | "build": "nuxt build",
12 | "start": "nuxt start",
13 | "generate": "nuxt generate",
14 | "post-update": "yarn upgrade --latest"
15 | },
16 | "devDependencies": {
17 | "@nuxt/types": "latest",
18 | "@nuxt/typescript-build": "latest"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
Counter : {{ counter }}
7 |
10 |
11 |
12 |
13 |
31 |
32 |
41 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/plugins/composition-api.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueCompositionApi from '@vue/composition-api'
3 |
4 | Vue.use(VueCompositionApi)
5 |
--------------------------------------------------------------------------------
/examples/composition-api/basic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "allowJs": true,
13 | "sourceMap": true,
14 | "strict": true,
15 | "noEmit": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "~/*": [
19 | "./*"
20 | ],
21 | "@/*": [
22 | "./*"
23 | ]
24 | },
25 | "types": [
26 | "@nuxt/types"
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt TypeScript with Composition API (minimal)
2 |
3 | https://typescript.nuxtjs.org/examples/composition-api/minimal
4 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | buildModules: ['@nuxt/typescript-build'],
3 | plugins: ['~/plugins/composition-api']
4 | }
5 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-composition-api-minimal",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "@vue/composition-api": "latest",
7 | "nuxt": "latest"
8 | },
9 | "scripts": {
10 | "dev": "nuxt",
11 | "build": "nuxt build",
12 | "start": "nuxt start",
13 | "generate": "nuxt generate",
14 | "post-update": "yarn upgrade --latest"
15 | },
16 | "devDependencies": {
17 | "@nuxt/types": "latest",
18 | "@nuxt/typescript-build": "latest"
19 | }
20 | }
21 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ message }}
4 |
5 |
6 |
7 |
20 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/plugins/composition-api.js:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 | import VueCompositionApi from '@vue/composition-api'
3 |
4 | Vue.use(VueCompositionApi)
5 |
--------------------------------------------------------------------------------
/examples/composition-api/minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "allowJs": true,
13 | "sourceMap": true,
14 | "strict": true,
15 | "noEmit": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "~/*": [
19 | "./*"
20 | ],
21 | "@/*": [
22 | "./*"
23 | ]
24 | },
25 | "types": [
26 | "@nuxt/types"
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/options-api/basic/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt TypeScript with Options API (basic)
2 |
3 | https://typescript.nuxtjs.org/examples/options-api/basic
4 |
--------------------------------------------------------------------------------
/examples/options-api/basic/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | buildModules: ['@nuxt/typescript-build']
3 | }
4 |
--------------------------------------------------------------------------------
/examples/options-api/basic/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-options-api-basic",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "nuxt": "latest"
7 | },
8 | "scripts": {
9 | "dev": "nuxt",
10 | "build": "nuxt build",
11 | "start": "nuxt start",
12 | "generate": "nuxt generate",
13 | "post-update": "yarn upgrade --latest"
14 | },
15 | "devDependencies": {
16 | "@nuxt/types": "latest",
17 | "@nuxt/typescript-build": "latest"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/examples/options-api/basic/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 |
6 |
Counter : {{ counter }}
7 |
10 |
11 |
12 |
13 |
32 |
33 |
42 |
--------------------------------------------------------------------------------
/examples/options-api/basic/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "allowJs": true,
13 | "sourceMap": true,
14 | "strict": true,
15 | "noEmit": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "~/*": [
19 | "./*"
20 | ],
21 | "@/*": [
22 | "./*"
23 | ]
24 | },
25 | "types": [
26 | "@nuxt/types"
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/options-api/minimal/README.md:
--------------------------------------------------------------------------------
1 | # Nuxt TypeScript with Options API (minimal)
2 |
3 | https://typescript.nuxtjs.org/examples/options-api/minimal
4 |
--------------------------------------------------------------------------------
/examples/options-api/minimal/nuxt.config.js:
--------------------------------------------------------------------------------
1 | export default {
2 | buildModules: ['@nuxt/typescript-build']
3 | }
4 |
--------------------------------------------------------------------------------
/examples/options-api/minimal/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "example-options-api-minimal",
3 | "version": "1.0.0",
4 | "private": true,
5 | "dependencies": {
6 | "nuxt": "latest"
7 | },
8 | "scripts": {
9 | "dev": "nuxt",
10 | "build": "nuxt build",
11 | "start": "nuxt start",
12 | "generate": "nuxt generate",
13 | "post-update": "yarn upgrade --latest"
14 | },
15 | "devDependencies": {
16 | "@nuxt/types": "latest",
17 | "@nuxt/typescript-build": "latest"
18 | }
19 | }
20 |
--------------------------------------------------------------------------------
/examples/options-api/minimal/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 |
3 | {{ message }}
4 |
5 |
6 |
7 |
20 |
--------------------------------------------------------------------------------
/examples/options-api/minimal/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "allowJs": true,
13 | "sourceMap": true,
14 | "strict": true,
15 | "noEmit": true,
16 | "baseUrl": ".",
17 | "paths": {
18 | "~/*": [
19 | "./*"
20 | ],
21 | "@/*": [
22 | "./*"
23 | ]
24 | },
25 | "types": [
26 | "@nuxt/types"
27 | ]
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/jest.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | testEnvironment: 'node',
3 | transform: {
4 | '^.+\\.ts$': 'ts-jest'
5 | },
6 | globals: {
7 | 'ts-jest': {
8 | tsconfig: 'tsconfig.test.json',
9 | diagnostics: {
10 | ignoreCodes: [2345]
11 | }
12 | }
13 | },
14 | collectCoverage: true,
15 | collectCoverageFrom: [
16 | 'packages/*/src/**/*.ts'
17 | ],
18 | coverageThreshold: {
19 | global: {
20 | branches: 100,
21 | functions: 100,
22 | lines: 100,
23 | statements: 100
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/lerna.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "independent",
3 | "npmClient": "yarn",
4 | "useWorkspaces": true,
5 | "conventionalCommits": true,
6 | "exact": true,
7 | "packages": [
8 | "packages/*"
9 | ],
10 | "command": {
11 | "publish": {
12 | "npmClient": "npm"
13 | },
14 | "init": {
15 | "exact": true
16 | }
17 | }
18 | }
19 |
--------------------------------------------------------------------------------
/netlify.toml:
--------------------------------------------------------------------------------
1 | # Global settings applied to the whole site.
2 | #
3 | # “base” is the directory to change to before starting build. If you set base:
4 | # that is where we will look for package.json/.nvmrc/etc, not repo root!
5 | # “command” is your build command.
6 | # “publish” is the directory to publish (relative to the root of your repo).
7 |
8 | [build]
9 | base = "docs"
10 | command = "yarn && yarn build"
11 | publish = "docs/dist"
12 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "private": true,
3 | "workspaces": [
4 | "packages/*"
5 | ],
6 | "scripts": {
7 | "build": "lerna run build",
8 | "lint": "eslint --ext .ts,.tsx,.js,.vue .",
9 | "lint:fix": "yarn lint --fix",
10 | "test": "yarn lint && jest"
11 | },
12 | "devDependencies": {
13 | "@nuxt/types": "npm:@nuxt/types-edge@latest",
14 | "@nuxtjs/eslint-config-typescript": "latest",
15 | "@types/jest": "latest",
16 | "@vue/composition-api": "latest",
17 | "codecov": "latest",
18 | "eslint": "latest",
19 | "jest": "latest",
20 | "lerna": "latest",
21 | "nuxt-edge": "latest",
22 | "ts-jest": "latest",
23 | "typescript": "~4.2",
24 | "vue-property-decorator": "latest"
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/packages/typescript-build/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # @nuxt/typescript-build
8 |
9 | ## 📑 License
10 |
11 | [MIT License](../../LICENSE)
12 |
13 | Copyright (c) Nuxt.js Team
14 |
--------------------------------------------------------------------------------
/packages/typescript-build/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nuxt/typescript-build",
3 | "version": "2.1.0",
4 | "description": "Nuxt.js TypeScript support",
5 | "repository": "nuxt/typescript",
6 | "license": "MIT",
7 | "files": [
8 | "dist"
9 | ],
10 | "main": "dist/index.js",
11 | "types": "dist/index.d.ts",
12 | "scripts": {
13 | "build": "yarn run clean && yarn compile",
14 | "clean": "rm -rf dist",
15 | "compile": "tsc"
16 | },
17 | "dependencies": {
18 | "consola": "^2.15.3",
19 | "fork-ts-checker-webpack-plugin": "^6.1.1",
20 | "ts-loader": "^8.0.17",
21 | "typescript": "~4.2"
22 | },
23 | "peerDependencies": {
24 | "@nuxt/types": ">=2.13.1"
25 | },
26 | "publishConfig": {
27 | "access": "public"
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/packages/typescript-build/src/index.ts:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import consola from 'consola'
3 | import { Module } from '@nuxt/types'
4 | import { Options as TsLoaderOptions } from 'ts-loader'
5 | import { ForkTsCheckerWebpackPluginOptions as TsCheckerOptions } from 'fork-ts-checker-webpack-plugin/lib/ForkTsCheckerWebpackPluginOptions'
6 | import { RuleSetUseItem } from 'webpack'
7 |
8 | export interface Options {
9 | ignoreNotFoundWarnings?: boolean
10 | loaders?: {
11 | ts?: Partial
12 | tsx?: Partial
13 | }
14 | typeCheck?: TsCheckerOptions | boolean
15 | }
16 |
17 | declare module '@nuxt/types' {
18 | interface NuxtOptions {
19 | typescript: Options
20 | }
21 | }
22 |
23 | const defaults: Options = {
24 | ignoreNotFoundWarnings: false,
25 | typeCheck: true
26 | }
27 |
28 | const tsModule: Module = function (moduleOptions) {
29 | // Combine options
30 | const options = Object.assign(
31 | defaults,
32 | this.options.typescript,
33 | moduleOptions
34 | )
35 |
36 | // Change color of CLI banner
37 | this.options.cli.bannerColor = 'blue'
38 |
39 | if (!this.options.extensions.includes('ts')) {
40 | this.options.extensions.push('ts')
41 | }
42 |
43 | // Extend Builder to handle .ts/.tsx files as routes and watch them
44 | this.options.build.additionalExtensions = ['ts', 'tsx']
45 |
46 | if (options.ignoreNotFoundWarnings) {
47 | this.options.build.warningIgnoreFilters!.push(warn =>
48 | warn.name === 'ModuleDependencyWarning' && /export .* was not found in /.test(warn.message)
49 | )
50 | }
51 |
52 | this.extendBuild((config, { isClient, isModern }) => {
53 | config.resolve!.extensions!.push('.ts', '.tsx')
54 |
55 | const jsxRuleLoaders = config.module!.rules.find(r => (r.test as RegExp).test('.jsx'))!.use as RuleSetUseItem[]
56 | const babelLoader = jsxRuleLoaders[jsxRuleLoaders.length - 1]
57 |
58 | config.module!.rules.push(...(['ts', 'tsx'] as const).map(ext =>
59 | ({
60 | test: new RegExp(`\\.${ext}$`, 'i'),
61 | use: [
62 | babelLoader,
63 | {
64 | loader: 'ts-loader',
65 | options: {
66 | transpileOnly: true,
67 | appendTsxSuffixTo: ext === 'tsx' ? [/\.vue$/] : [],
68 | ...(options.loaders && options.loaders[ext])
69 | }
70 | }
71 | ]
72 | })
73 | ))
74 |
75 | if (options.typeCheck && isClient && !isModern) {
76 | const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
77 | config.plugins!.push(new ForkTsCheckerWebpackPlugin(Object.assign({
78 | typescript: {
79 | configFile: path.resolve(this.options.rootDir!, 'tsconfig.json'),
80 | extensions: {
81 | vue: true
82 | }
83 | },
84 | logger: consola.withScope('nuxt:typescript')
85 | } as TsCheckerOptions, options.typeCheck)))
86 | }
87 | })
88 | }
89 |
90 | export default tsModule
91 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/@types/vue.d.ts:
--------------------------------------------------------------------------------
1 | declare module '*.vue' {
2 | import Vue from 'vue'
3 | export default Vue
4 | }
5 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/nuxt.config.ts:
--------------------------------------------------------------------------------
1 | import { Configuration } from '@nuxt/types'
2 | import logger from './serverMiddlewares/logger'
3 |
4 | const config: Configuration = {
5 | buildModules: [
6 | '@nuxt/typescript-build'
7 | ],
8 | serverMiddleware: [
9 | logger
10 | ],
11 | telemetry: false
12 | }
13 |
14 | export default config
15 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/pages/about.ts:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | export default Vue.extend({
4 | name: 'About',
5 | render (h) {
6 | const text: string = 'About Page'
7 | return h('div', text)
8 | }
9 | })
10 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/pages/contact.tsx:
--------------------------------------------------------------------------------
1 | import Vue from 'vue'
2 |
3 | export default Vue.extend({
4 | name: 'Contact',
5 | data () {
6 | const text: string = 'Contact Page'
7 | return { text }
8 | },
9 | render () {
10 | return { this.text }
11 | }
12 | })
13 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/pages/index.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ text }}
3 |
4 |
5 |
15 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/pages/interface.vue:
--------------------------------------------------------------------------------
1 |
2 | {{ test.attributes.text }}
3 |
4 |
5 |
25 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/serverMiddlewares/logger.ts:
--------------------------------------------------------------------------------
1 | import { ServerMiddleware } from '@nuxt/types'
2 |
3 | const logger: ServerMiddleware = (_req, _res, next) => {
4 | // eslint-disable-next-line
5 | console.log(new Date(), 'log something !')
6 | next()
7 | }
8 |
9 | export default logger
10 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/shims-tsx.d.ts:
--------------------------------------------------------------------------------
1 | // eslint-disable-next-line
2 | import Vue, { VNode } from 'vue'
3 |
4 | declare global {
5 | namespace JSX {
6 | interface Element extends VNode {}
7 | interface ElementClass extends Vue {}
8 | interface IntrinsicElements {
9 | [elem: string]: any
10 | }
11 | }
12 | }
13 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/fixture/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2018",
4 | "module": "ESNext",
5 | "moduleResolution": "Node",
6 | "lib": [
7 | "ESNext",
8 | "ESNext.AsyncIterable",
9 | "DOM"
10 | ],
11 | "esModuleInterop": true,
12 | "allowJs": true,
13 | "jsx": "preserve",
14 | "sourceMap": true,
15 | "strict": true,
16 | "noEmit": true,
17 | "baseUrl": ".",
18 | "paths": {
19 | "~/*": [
20 | "./*"
21 | ],
22 | "@/*": [
23 | "./*"
24 | ]
25 | },
26 | "types": [
27 | "@nuxt/types"
28 | ]
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/packages/typescript-build/test/module.test.ts:
--------------------------------------------------------------------------------
1 |
2 | import ForkTsCheckerWebpackPlugin from 'fork-ts-checker-webpack-plugin'
3 | import { Nuxt } from '@nuxt/core-edge'
4 | import { Builder } from '@nuxt/builder-edge'
5 | import { BundleBuilder } from '@nuxt/webpack-edge'
6 | import { Configuration as WebpackConfiguration, RuleSetLoader } from 'webpack'
7 | import { NuxtConfig, NuxtOptions } from '@nuxt/types'
8 | import { Options as TsLoaderOptions } from 'ts-loader'
9 |
10 | import tsModule from '../src'
11 |
12 | jest.setTimeout(60000)
13 | jest.mock('fork-ts-checker-webpack-plugin', () => {
14 | return jest.fn().mockImplementation(() => ({
15 | apply () {}
16 | }))
17 | })
18 |
19 | interface BuilderInstance {
20 | nuxt: {
21 | options: NuxtOptions,
22 | close(): void
23 | }
24 |
25 | bundleBuilder: {
26 | getWebpackConfig(name: string): WebpackConfiguration
27 | }
28 |
29 | build(): void
30 | }
31 |
32 | const buildWithTsModule = async (config: NuxtConfig = {}): Promise => {
33 | const nuxt = new Nuxt({
34 | build: {
35 | warningIgnoreFilters: []
36 | },
37 | ...config
38 | })
39 |
40 | await nuxt.moduleContainer.addModule(tsModule)
41 | const builder: BuilderInstance = new Builder(nuxt, BundleBuilder)
42 | await builder.build()
43 |
44 | return builder
45 | }
46 |
47 | describe('module', () => {
48 | let builder: BuilderInstance
49 |
50 | beforeEach(() => {
51 | // @ts-ignore
52 | ForkTsCheckerWebpackPlugin.mockClear()
53 | })
54 |
55 | test('with default options', async () => {
56 | builder = await buildWithTsModule()
57 |
58 | expect(builder.nuxt.options.extensions).toContain('ts')
59 |
60 | expect(builder.nuxt.options.build.additionalExtensions).toHaveLength(2)
61 | expect(builder.nuxt.options.build.additionalExtensions).toEqual(['ts', 'tsx'])
62 |
63 | expect(ForkTsCheckerWebpackPlugin).toHaveBeenCalledTimes(1)
64 | })
65 |
66 | test('register ts extension once', async () => {
67 | builder = await buildWithTsModule({
68 | extensions: ['ts']
69 | })
70 |
71 | expect(builder.nuxt.options.extensions.filter(ext => ext === 'ts')).toHaveLength(1)
72 | })
73 |
74 | test('without typeCheck', async () => {
75 | builder = await buildWithTsModule({
76 | typescript: {
77 | typeCheck: false
78 | }
79 | })
80 |
81 | expect(ForkTsCheckerWebpackPlugin).not.toHaveBeenCalled()
82 | })
83 |
84 | test('with ignoreNotFoundWarnings', async () => {
85 | builder = await buildWithTsModule({
86 | typescript: {
87 | ignoreNotFoundWarnings: true
88 | }
89 | })
90 |
91 | expect(builder.nuxt.options.build.warningIgnoreFilters).toHaveLength(1)
92 | expect(builder.nuxt.options.build.warningIgnoreFilters).toEqual([expect.any(Function)])
93 | expect(builder.nuxt.options.build.warningIgnoreFilters).toEqual(true)
97 | })
98 |
99 | test('with custom ts-loader options', async () => {
100 | const loaderOptions = {
101 | transpileOnly: false
102 | } as TsLoaderOptions
103 |
104 | builder = await buildWithTsModule({
105 | typescript: {
106 | loaders: {
107 | ts: loaderOptions,
108 | tsx: loaderOptions
109 | }
110 | }
111 | })
112 |
113 | const webpackConfig = builder.bundleBuilder.getWebpackConfig('Client')
114 |
115 | const tsLoader = (webpackConfig.module!.rules.find(r => (r.test as RegExp).test('file.ts'))!.use as RuleSetLoader[]).find(u => u.loader === 'ts-loader')
116 |
117 | expect(tsLoader).toBeDefined()
118 | expect((tsLoader!.options as TsLoaderOptions).transpileOnly).toBe(false)
119 |
120 | const tsxLoader = (webpackConfig.module!.rules.find(r => (r.test as RegExp).test('file.tsx'))!.use as RuleSetLoader[]).find(u => u.loader === 'ts-loader')
121 |
122 | expect(tsxLoader).toBeDefined()
123 | expect((tsxLoader!.options as TsLoaderOptions).transpileOnly).toBe(false)
124 | })
125 |
126 | afterEach(async () => {
127 | await builder.nuxt.close()
128 | })
129 | })
130 |
--------------------------------------------------------------------------------
/packages/typescript-build/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist",
5 | "declaration": true,
6 | "sourceMap": true
7 | },
8 | "include": [
9 | "src/**/*"
10 | ]
11 | }
12 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | # @nuxt/typescript-runtime
8 |
9 | ## 📑 License
10 |
11 | [MIT License](../../LICENSE)
12 |
13 | Copyright (c) Nuxt.js Team
14 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/bin/nuxt-ts.js:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env node
2 |
3 | let cli, hooks, version
4 |
5 | try {
6 | cli = require('@nuxt/cli')
7 | version = require('@nuxt/cli/package.json').version
8 | } catch (err) {
9 | cli = require('@nuxt/cli-edge')
10 | version = require('@nuxt/cli-edge/package.json').version
11 | }
12 |
13 | const { coerce, gte } = require('semver')
14 |
15 | if (gte(coerce(version), '2.15.0')) {
16 | const chalk = require('chalk')
17 | const consola = require('consola')
18 | consola.warn(chalk`You're using Nuxt {green ${version}}, which includes built-in TypeScript {blue runtime} support`)
19 | consola.warn(chalk`You can safely use {green nuxt} instead of {yellow nuxt-ts} and remove {blue @nuxt/typescript-runtime} package`)
20 | hooks = {}
21 | } else {
22 | hooks = require('..').hooks
23 | }
24 |
25 | cli.run(null, hooks)
26 | .catch((error) => {
27 | require('consola').fatal(error)
28 | require('exit')(2)
29 | })
30 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "@nuxt/typescript-runtime",
3 | "version": "2.1.0",
4 | "description": "Nuxt.js TypeScript Runtime support",
5 | "repository": "nuxt/typescript",
6 | "license": "MIT",
7 | "files": [
8 | "bin",
9 | "dist"
10 | ],
11 | "bin": {
12 | "nuxt-ts": "bin/nuxt-ts.js",
13 | "nuxts": "bin/nuxt-ts.js"
14 | },
15 | "main": "dist/index.js",
16 | "scripts": {
17 | "build": "yarn run clean && yarn compile",
18 | "clean": "rm -rf dist",
19 | "compile": "tsc"
20 | },
21 | "dependencies": {
22 | "ts-node": "^9.1.1",
23 | "typescript": "~4.2"
24 | },
25 | "peerDependencies": {
26 | "@nuxt/types": ">=2.13.1"
27 | },
28 | "publishConfig": {
29 | "access": "public"
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/src/index.ts:
--------------------------------------------------------------------------------
1 | import { resolve } from 'path'
2 | import { register } from 'ts-node'
3 | import { Hooks } from '@nuxt/types/cli'
4 |
5 | const hooks: Hooks = {
6 | 'run:before' ({ argv, rootDir }) {
7 | const customPath = argv.find((_arg, index) => index > 0 && argv[index - 1] === '--tsconfig')
8 | const tsConfigPath = resolve(customPath || rootDir, customPath && customPath.endsWith('.json') ? '' : 'tsconfig.json')
9 |
10 | register({
11 | project: tsConfigPath,
12 | compilerOptions: {
13 | module: 'commonjs'
14 | },
15 | transpileOnly: true
16 | })
17 | },
18 |
19 | config (config) {
20 | config.extensions = [...(config.extensions || []), 'ts']
21 | }
22 | }
23 |
24 | export {
25 | hooks
26 | }
27 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/test/hooks.test.ts:
--------------------------------------------------------------------------------
1 | import path from 'path'
2 | import { register } from 'ts-node'
3 | import { NuxtConfig } from '@nuxt/types'
4 | import { hooks } from '../src'
5 |
6 | jest.mock('ts-node')
7 |
8 | describe('run:before hook', () => {
9 | beforeEach(() => {
10 | jest.clearAllMocks()
11 | })
12 |
13 | test('registers ts-node', () => {
14 | hooks['run:before']!({ argv: [], command: null, rootDir: 'path' })
15 |
16 | expect(register).toHaveBeenCalledWith({
17 | project: path.resolve('path', 'tsconfig.json'),
18 | compilerOptions: {
19 | module: 'commonjs'
20 | },
21 | transpileOnly: true
22 | })
23 | })
24 |
25 | test('registers ts-node (custom tsconfig.json path)', () => {
26 | hooks['run:before']!({ argv: ['--tsconfig', 'custom/tsconfig.json'], command: null, rootDir: 'path' })
27 |
28 | expect(register).toHaveBeenCalledWith({
29 | project: path.resolve('custom/tsconfig.json'),
30 | compilerOptions: {
31 | module: 'commonjs'
32 | },
33 | transpileOnly: true
34 | })
35 | })
36 |
37 | test('registers ts-node (custom tsconfig.json dir path)', () => {
38 | hooks['run:before']!({ argv: ['--tsconfig', 'custom'], command: null, rootDir: 'path' })
39 |
40 | expect(register).toHaveBeenCalledWith({
41 | project: path.resolve('custom/tsconfig.json'),
42 | compilerOptions: {
43 | module: 'commonjs'
44 | },
45 | transpileOnly: true
46 | })
47 | })
48 | })
49 |
50 | describe('config hook', () => {
51 | test('adds ts extension (config.extensions is: defined)', () => {
52 | const config = { extensions: [] }
53 |
54 | hooks.config!(config)
55 |
56 | expect(config.extensions).toContain('ts')
57 | })
58 |
59 | test('adds ts extension (config.extensions is: undefined)', () => {
60 | const config: NuxtConfig = {}
61 |
62 | hooks.config!(config)
63 |
64 | expect(config.extensions).toContain('ts')
65 | })
66 | })
67 |
--------------------------------------------------------------------------------
/packages/typescript-runtime/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "../../tsconfig.json",
3 | "compilerOptions": {
4 | "outDir": "dist"
5 | },
6 | "include": [
7 | "src/**/*"
8 | ]
9 | }
10 |
--------------------------------------------------------------------------------
/renovate.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "@nuxtjs"
4 | ],
5 | "lockFileMaintenance": {
6 | "enabled": true
7 | },
8 | "labels": [
9 | "dependencies"
10 | ],
11 | "ignoreDeps": [
12 | "@nuxt/types",
13 | "typescript"
14 | ]
15 | }
16 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "lib": ["DOM", "ESNext"],
5 | "module": "CommonJS",
6 | "moduleResolution": "Node",
7 | "esModuleInterop": true,
8 | "strict": true,
9 | "noFallthroughCasesInSwitch": true,
10 | "noImplicitReturns": true,
11 | "stripInternal": true,
12 | "noUnusedLocals": true
13 | }
14 | }
15 |
--------------------------------------------------------------------------------
/tsconfig.test.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES6",
4 | "lib": ["DOM", "ESNext"],
5 | "module": "ESNext",
6 | "moduleResolution": "Node",
7 | "skipLibCheck": true,
8 | "esModuleInterop": true,
9 | "strict": true,
10 | "noImplicitAny": false,
11 | "noFallthroughCasesInSwitch": true,
12 | "noImplicitReturns": true,
13 | "stripInternal": true,
14 | "noUnusedLocals": true
15 | },
16 | "include": ["packages/*/test/**/*.ts"]
17 | }
18 |
--------------------------------------------------------------------------------