├── .editorconfig ├── .eslintignore ├── .eslintrc.js ├── .github └── workflows │ └── ci.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── commitlint.config.js ├── husky.config.js ├── jest.config.js ├── lib ├── module.js └── plugin.js ├── package.json ├── renovate.json ├── test ├── __snapshots__ │ └── watch.test.js.snap ├── basic.test.js ├── empty-suffixes.test.js ├── fixture │ ├── basic │ │ ├── components │ │ │ ├── foo.global.vue │ │ │ └── sub │ │ │ │ └── bar.global.vue │ │ ├── nuxt.config.js │ │ └── pages │ │ │ └── index.vue │ ├── empty-suffixes │ │ ├── components │ │ │ ├── foo.vue │ │ │ └── sub │ │ │ │ └── bar.vue │ │ ├── nuxt.config.js │ │ └── pages │ │ │ └── index.vue │ ├── multiple-dirs │ │ ├── external │ │ │ └── bar.global.vue │ │ ├── libs │ │ │ └── foo.global.vue │ │ ├── nuxt.config.js │ │ └── pages │ │ │ └── index.vue │ ├── multiple-suffixes │ │ ├── components │ │ │ ├── foo.vue │ │ │ └── sub │ │ │ │ └── bar.global.vue │ │ ├── nuxt.config.js │ │ └── pages │ │ │ └── index.vue │ └── pascal │ │ ├── components │ │ ├── Bar.global.vue │ │ ├── bar-foo.global.vue │ │ ├── foo.global.vue │ │ └── foo_bar.global.vue │ │ ├── nuxt.config.js │ │ └── pages │ │ └── index.vue ├── multiple-dirs.test.js ├── multiple-suffixes.test.js ├── pascal.test.js └── watch.test.js └── 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 | # Common 2 | node_modules 3 | dist 4 | .nuxt 5 | coverage 6 | 7 | # Plugin 8 | lib/plugin.js 9 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | extends: [ 4 | '@nuxtjs' 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | name: ci 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request: 8 | branches: 9 | - master 10 | 11 | jobs: 12 | ci: 13 | runs-on: ${{ matrix.os }} 14 | 15 | strategy: 16 | matrix: 17 | # os: [ubuntu-latest, macos-latest, windows-latest] 18 | os: [ubuntu-latest] 19 | node: [10] 20 | 21 | steps: 22 | - uses: actions/setup-node@v1 23 | with: 24 | node-version: ${{ matrix.node }} 25 | 26 | - name: checkout 27 | uses: actions/checkout@master 28 | 29 | - name: cache node_modules 30 | uses: actions/cache@v2 31 | with: 32 | path: node_modules 33 | key: ${{ matrix.os }}-node-v${{ matrix.node }}-deps-${{ hashFiles(format('{0}{1}', github.workspace, '/yarn.lock')) }} 34 | 35 | - name: Install dependencies 36 | if: steps.cache.outputs.cache-hit != 'true' 37 | run: yarn 38 | 39 | - name: Lint 40 | run: yarn lint 41 | 42 | - name: Test 43 | run: yarn test 44 | 45 | - name: Coverage 46 | uses: codecov/codecov-action@v1 47 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | *.iml 3 | .idea 4 | *.log* 5 | .nuxt 6 | .vscode 7 | .DS_Store 8 | coverage 9 | dist 10 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. See [standard-version](https://github.com/conventional-changelog/standard-version) for commit guidelines. 4 | 5 | ### [0.6.1](https://github.com/nuxt-community/global-components/compare/v0.6.0...v0.6.1) (2020-02-11) 6 | 7 | 8 | ### Bug Fixes 9 | 10 | * non-posix pattern given to globby on win32 ([#15](https://github.com/nuxt-community/global-components/issues/15)) ([c4f165c](https://github.com/nuxt-community/global-components/commit/c4f165c)) 11 | 12 | ## [0.6.0](https://github.com/nuxt-community/global-components/compare/v0.5.1...v0.6.0) (2020-01-27) 13 | 14 | 15 | ### ⚠ BREAKING CHANGES 16 | 17 | * The components will be renamed of snake, kebab case to pascal 18 | 19 | ### Features 20 | 21 | * snake, kebab case to pascal ([#8](https://github.com/nuxt-community/global-components/issues/8)) ([943bb4c](https://github.com/nuxt-community/global-components/commit/943bb4c)) 22 | 23 | ### [0.5.1](https://github.com/nuxt-community/global-components/compare/v0.5.0...v0.5.1) (2020-01-27) 24 | 25 | 26 | ### Bug Fixes 27 | 28 | * empty suffixes ([#14](https://github.com/nuxt-community/global-components/issues/14)) ([4325117](https://github.com/nuxt-community/global-components/commit/4325117)) 29 | 30 | ## [0.5.0](https://github.com/nuxt-community/global-components/compare/v0.4.1...v0.5.0) (2020-01-23) 31 | 32 | 33 | ### Features 34 | 35 | * multiple dirs ([#13](https://github.com/nuxt-community/global-components/issues/13)) ([7fb4be4](https://github.com/nuxt-community/global-components/commit/7fb4be4968ecbca25b2f92b8b6a0c3d6f9571234)) 36 | 37 | 38 | ### Bug Fixes 39 | 40 | * typo in globby options ([#12](https://github.com/nuxt-community/global-components/issues/12)) ([f267120](https://github.com/nuxt-community/global-components/commit/f267120ab6e9201a22189b0d0e417a5d5917c4a2)) 41 | 42 | ### [0.4.1](https://github.com/nuxt-community/global-components/compare/v0.4.0...v0.4.1) (2020-01-19) 43 | 44 | 45 | ### Bug Fixes 46 | 47 | * **module:** only watch components directory in dev mode ([#9](https://github.com/nuxt-community/global-components/issues/9)) ([870835d](https://github.com/nuxt-community/global-components/commit/870835d)) 48 | 49 | ## [0.4.0](https://github.com/nuxt-community/global-components/compare/v0.3.1...v0.4.0) (2020-01-14) 50 | 51 | 52 | ### Features 53 | 54 | * watch components directory and rebuild ([#6](https://github.com/nuxt-community/global-components/issues/6)) ([2e49ea8](https://github.com/nuxt-community/global-components/commit/2e49ea8)) 55 | 56 | ### [0.3.1](https://github.com/nuxt-community/global-components/compare/v0.3.0...v0.3.1) (2020-01-09) 57 | 58 | 59 | ### Bug Fixes 60 | 61 | * use `reduce` and `concat` instead of `flatMap` ([911fef5](https://github.com/nuxt-community/global-components/commit/911fef5)) 62 | 63 | ## [0.3.0](https://github.com/nuxt-community/global-components/compare/v0.2.0...v0.3.0) (2019-12-11) 64 | 65 | 66 | ### Features 67 | 68 | * option to ignore name detection ([82049b3](https://github.com/nuxt-community/global-components/commit/82049b3)) 69 | 70 | ## [0.2.0](https://github.com/nuxt-community/global-components/compare/v0.1.0...v0.2.0) (2019-10-17) 71 | 72 | 73 | ### Features 74 | 75 | * add option `suffixes` ([ff34db2](https://github.com/nuxt-community/global-components/commit/ff34db29ebaf589d35012aeb4053980c0b92fbe0)) 76 | 77 | ## 0.1.0 (2019-10-01) 78 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) Nuxt Community 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 | # @nuxtjs/global-components 2 | 3 | [![npm version][npm-version-src]][npm-version-href] 4 | [![npm downloads][npm-downloads-src]][npm-downloads-href] 5 | [![Github Actions CI][github-actions-ci-src]][github-actions-ci-href] 6 | [![Codecov][codecov-src]][codecov-href] 7 | [![License][license-src]][license-href] 8 | 9 | > Module to register global components for Nuxt.js 10 | 11 | [📖 **Release Notes**](./CHANGELOG.md) 12 | 13 | 14 | ## :warning: Important 15 | 16 | NuxtJS Team released [@nuxt/components](https://github.com/nuxt/components) to auto import components when used in templates, allowing better performances and features. 17 | 18 | If you want to migrate from this module, you will simply have to remove the `.global` suffix. 19 | 20 | ## Usage 21 | 22 | Suffix your components with `.global.{ext}` to declare your global components. 23 | 24 | ```bash 25 | components/ 26 | my-component.vue # local component, import it to use it 27 | my-button.global.vue # global component, no need to register it! 28 | ``` 29 | 30 | See [live demo](https://codesandbox.io/s/nuxtjs-global-components-ujtoq). 31 | 32 | ## Setup 33 | 34 | 1. Add `@nuxtjs/global-components` dependency to your project 35 | 36 | ```bash 37 | yarn add --dev @nuxtjs/global-components # or npm install --save-dev @nuxtjs/global-components 38 | ``` 39 | 40 | 2. Add `@nuxtjs/global-components` to the `buildModules` section of `nuxt.config.js` 41 | 42 | ```js 43 | export default { 44 | buildModules: [ 45 | // Simple usage 46 | '@nuxtjs/global-components', 47 | 48 | // With options 49 | ['@nuxtjs/global-components', { /* module options */ }] 50 | ] 51 | } 52 | ``` 53 | 54 | :warning: If you are using Nuxt **< v2.9** you have to install the module as a `dependency` (No `--dev` or `--save-dev` flags) and use `modules` section in `nuxt.config.js` instead of `buildModules`. 55 | 56 | ### Using top level options 57 | 58 | ```js 59 | export default { 60 | buildModules: [ 61 | '@nuxtjs/global-components' 62 | ], 63 | globalComponents: { 64 | /* module options */ 65 | } 66 | } 67 | ``` 68 | 69 | ## Options 70 | 71 | ### `dir` 72 | 73 | - Type: `String|Array` 74 | - Default: `components` 75 | 76 | A list of directories to find components inside your nuxt project. 77 | 78 | ### `suffixes` 79 | 80 | - Type: `Array` 81 | - Default: `['global']` 82 | 83 | The suffixes that files can contain. 84 | 85 | ### `extensions` 86 | 87 | - Type: `Array` 88 | - Default: `['vue', 'js', 'ts']` 89 | 90 | The extensions that files can contain. 91 | 92 | ### `ignore` 93 | 94 | - Type: `Array` 95 | - Default: `[]` 96 | 97 | An array of glob patterns to exclude matches. 98 | 99 | ### `ignoreNameDetection` 100 | 101 | - Type: `Boolean` 102 | - Default: `false` 103 | 104 | Ignore name detection using prototype names. 105 | 106 | ## License 107 | 108 | [MIT License](./LICENSE) 109 | 110 | Insipired by [nuxtjs.org](https://github.com/nuxt/nuxtjs.org/tree/master/modules/components) 111 | 112 | Copyright (c) Nuxt Community 113 | 114 | 115 | [npm-version-src]: https://img.shields.io/npm/v/@nuxtjs/global-components/latest.svg 116 | [npm-version-href]: https://npmjs.com/package/@nuxtjs/global-components 117 | 118 | [npm-downloads-src]: https://img.shields.io/npm/dt/@nuxtjs/global-components.svg 119 | [npm-downloads-href]: https://npmjs.com/package/@nuxtjs/global-components 120 | 121 | [github-actions-ci-src]: https://github.com/nuxt-community/global-components/workflows/ci/badge.svg 122 | [github-actions-ci-href]: https://github.com/nuxt-community/global-components/actions?query=workflow%3Aci 123 | 124 | [codecov-src]: https://img.shields.io/codecov/c/github/nuxt-community/global-components.svg 125 | [codecov-href]: https://codecov.io/gh/nuxt-community/global-components 126 | 127 | [license-src]: https://img.shields.io/npm/l/@nuxtjs/global-components.svg 128 | [license-href]: https://npmjs.com/package/@nuxtjs/global-components 129 | -------------------------------------------------------------------------------- /commitlint.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | extends: [ 3 | '@commitlint/config-conventional' 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /husky.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | hooks: { 3 | 'commit-msg': 'commitlint -E HUSKY_GIT_PARAMS', 4 | 'pre-commit': 'yarn lint', 5 | 'pre-push': 'yarn lint' 6 | } 7 | } 8 | -------------------------------------------------------------------------------- /jest.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | collectCoverage: true, 3 | collectCoverageFrom: ['lib/**/*.js', '!lib/plugin.js'], 4 | testEnvironment: 'node' 5 | } 6 | -------------------------------------------------------------------------------- /lib/module.js: -------------------------------------------------------------------------------- 1 | const { posix: { join }, resolve } = require('path') 2 | const globby = require('globby') 3 | const chokidar = require('chokidar') 4 | 5 | module.exports = function (moduleOptions) { 6 | const { options } = this.nuxt 7 | 8 | // Merge options and apply defaults 9 | const { dir, suffixes, extensions, ignore, ignoreNameDetection } = { 10 | dir: options.dir.components || 'components', 11 | suffixes: ['global'], 12 | extensions: ['vue', 'js', 'ts'], 13 | ignore: [], 14 | ignoreNameDetection: false, 15 | ...moduleOptions, 16 | ...this.options['global-components'], 17 | ...this.options.globalComponents 18 | } 19 | 20 | // Compute suffix with extensions array 21 | const suffixesWithExtensions = getSuffixesWithExtensions(suffixes, extensions) 22 | 23 | // Remove extension 24 | const removeExtension = name => name.replace(new RegExp(`\\.(${suffixesWithExtensions.join('|')})$`), '') 25 | 26 | // Resolve components dirs 27 | const dirs = Array.isArray(dir) ? dir : [dir] 28 | const componentsDir = dirs.map(d => resolve(options.srcDir, d)) 29 | 30 | // Patterns 31 | const patterns = dirs.map(d => join(d, `/**/*.(${suffixesWithExtensions.join('|')})`)) 32 | 33 | // Plugin options context 34 | const pluginOptions = { 35 | components: [], 36 | ignoreNameDetection 37 | } 38 | 39 | // Scans global components and updates context 40 | const scanGlobalComponents = async () => { 41 | const fileNames = await globby(patterns, { 42 | cwd: options.srcDir, 43 | ignore, 44 | absolute: false, 45 | objectMode: true, 46 | onlyFiles: true 47 | }) 48 | 49 | const globalComponents = fileNames.map(({ name, path }) => { 50 | return { 51 | name: toPascal(removeExtension(name)), 52 | path: `~/${path}` 53 | } 54 | }) 55 | 56 | const changesDetected = !deepEqual(globalComponents, pluginOptions.components) 57 | pluginOptions.components = globalComponents 58 | return changesDetected 59 | } 60 | 61 | // Hook on builder 62 | this.nuxt.hook('build:before', async (builder) => { 63 | // Scan components once 64 | await scanGlobalComponents() 65 | 66 | // Watch components directory for dev mode 67 | if (this.options.dev) { 68 | const watcher = chokidar.watch(componentsDir, options.watchers.chokidar) 69 | watcher.on('all', async (eventName) => { 70 | if (!['add', 'unlink'].includes(eventName)) { 71 | return 72 | } 73 | const changesDetected = await scanGlobalComponents() 74 | if (changesDetected) { 75 | builder.generateRoutesAndFiles() 76 | } 77 | }) 78 | 79 | // Close watcher on nuxt close 80 | this.nuxt.hook('close', () => { 81 | watcher.close() 82 | }) 83 | } 84 | }) 85 | 86 | // Add global-components plugin 87 | this.addPlugin({ 88 | src: resolve(__dirname, 'plugin.js'), 89 | fileName: 'global-components.js', 90 | options: pluginOptions 91 | }) 92 | } 93 | 94 | function getSuffixesWithExtensions (suffixes, extensions) { 95 | if (suffixes.length < 1) { 96 | return extensions 97 | } 98 | 99 | return suffixes.reduce((acc, suffix) => { 100 | const suffixWithExtension = extensions.map(extension => `${suffix}${(suffix ? '.' : '')}${extension}`) 101 | 102 | return acc.concat(suffixWithExtension) 103 | }, []) 104 | } 105 | 106 | function deepEqual (a, b) { 107 | return JSON.stringify(a) === JSON.stringify(b) 108 | } 109 | 110 | function toPascal (name) { 111 | const camelCase = name.replace(/([-_]\w)/g, g => g[1].toUpperCase()) 112 | return camelCase[0].toUpperCase() + camelCase.substr(1) 113 | } 114 | 115 | module.exports.meta = require('../package.json') 116 | -------------------------------------------------------------------------------- /lib/plugin.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | <% options.components.forEach(({ name, path }) => { %>import <%= name %> from '<%= path %>' 3 | <% }) %> 4 | 5 | <% options.components.forEach(({ name }) => { %> 6 | Vue.component(<% if (!options.ignoreNameDetection) { %><%= name %>.name || <% } %>'<%= name %>', <%= name %>) 7 | <% }) %> 8 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "@nuxtjs/global-components", 3 | "version": "0.6.1", 4 | "description": "Module to register global components for Nuxt.js", 5 | "repository": "nuxt-community/global-components", 6 | "license": "MIT", 7 | "contributors": [ 8 | "Ricardo Gobbo de Souza " 9 | ], 10 | "main": "lib/module.js", 11 | "files": [ 12 | "lib" 13 | ], 14 | "scripts": { 15 | "lint": "eslint --ext .js,.vue .", 16 | "release": "yarn test && standard-version && git push --follow-tags && npm publish", 17 | "test": "yarn lint && jest" 18 | }, 19 | "dependencies": { 20 | "chokidar": "^3.4.3", 21 | "globby": "^11.0.1" 22 | }, 23 | "devDependencies": { 24 | "@commitlint/cli": "latest", 25 | "@commitlint/config-conventional": "latest", 26 | "@nuxtjs/eslint-config": "latest", 27 | "@nuxtjs/module-test-utils": "latest", 28 | "eslint": "latest", 29 | "husky": "latest", 30 | "jest": "latest", 31 | "nuxt-edge": "latest", 32 | "standard-version": "latest" 33 | }, 34 | "publishConfig": { 35 | "access": "public" 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /renovate.json: -------------------------------------------------------------------------------- 1 | { 2 | "extends": [ 3 | "@nuxtjs" 4 | ] 5 | } 6 | -------------------------------------------------------------------------------- /test/__snapshots__/watch.test.js.snap: -------------------------------------------------------------------------------- 1 | // Jest Snapshot v1, https://goo.gl/fbAQLP 2 | 3 | exports[`watch discover components and pass as componentOptions 1`] = ` 4 | Object { 5 | "components": Array [ 6 | Object { 7 | "name": "A.js", 8 | "path": "~//project/nuxt/a.js", 9 | }, 10 | Object { 11 | "name": "B", 12 | "path": "~//project/nuxt/b.global.js", 13 | }, 14 | Object { 15 | "name": "C", 16 | "path": "~//project/nuxt/c.global.js", 17 | }, 18 | ], 19 | "ignoreNameDetection": false, 20 | } 21 | `; 22 | -------------------------------------------------------------------------------- /test/basic.test.js: -------------------------------------------------------------------------------- 1 | const { setup, loadConfig, get } = require('@nuxtjs/module-test-utils') 2 | 3 | describe('basic', () => { 4 | let nuxt 5 | 6 | beforeAll(async () => { 7 | ({ nuxt } = (await setup(loadConfig(__dirname, 'basic')))) 8 | }, 60000) 9 | 10 | afterAll(async () => { 11 | await nuxt.close() 12 | }) 13 | 14 | test('render', async () => { 15 | const html = await get('/') 16 | expect(html).toContain('Works!') 17 | expect(html).toContain('bar content') 18 | expect(html).toContain('foo content') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/empty-suffixes.test.js: -------------------------------------------------------------------------------- 1 | const { setup, loadConfig, get } = require('@nuxtjs/module-test-utils') 2 | 3 | describe('empty-suffixes', () => { 4 | let nuxt 5 | 6 | beforeAll(async () => { 7 | ({ nuxt } = (await setup(loadConfig(__dirname, 'empty-suffixes')))) 8 | }, 60000) 9 | 10 | afterAll(async () => { 11 | await nuxt.close() 12 | }) 13 | 14 | test('render', async () => { 15 | const html = await get('/') 16 | expect(html).toContain('Works!') 17 | expect(html).toContain('foo content') 18 | expect(html).toContain('bar content') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/fixture/basic/components/foo.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/basic/components/sub/bar.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/basic/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: __dirname, 3 | modules: [ 4 | { handler: require('../../../') } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixture/basic/pages/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixture/empty-suffixes/components/foo.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/empty-suffixes/components/sub/bar.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/empty-suffixes/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: __dirname, 3 | modules: [ 4 | { handler: require('../../../') } 5 | ], 6 | globalComponents: { 7 | suffixes: [] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixture/empty-suffixes/pages/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixture/multiple-dirs/external/bar.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/multiple-dirs/libs/foo.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/multiple-dirs/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: __dirname, 3 | modules: [ 4 | { handler: require('../../../') } 5 | ], 6 | globalComponents: { 7 | dir: ['libs', 'external'] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixture/multiple-dirs/pages/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixture/multiple-suffixes/components/foo.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/multiple-suffixes/components/sub/bar.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/multiple-suffixes/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: __dirname, 3 | modules: [ 4 | { handler: require('../../../') } 5 | ], 6 | globalComponents: { 7 | suffixes: ['global', ''] 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /test/fixture/multiple-suffixes/pages/index.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 14 | -------------------------------------------------------------------------------- /test/fixture/pascal/components/Bar.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/pascal/components/bar-foo.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/pascal/components/foo.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/pascal/components/foo_bar.global.vue: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /test/fixture/pascal/nuxt.config.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | rootDir: __dirname, 3 | modules: [ 4 | { handler: require('../../../') } 5 | ] 6 | } 7 | -------------------------------------------------------------------------------- /test/fixture/pascal/pages/index.vue: -------------------------------------------------------------------------------- 1 | 10 | 11 | 16 | -------------------------------------------------------------------------------- /test/multiple-dirs.test.js: -------------------------------------------------------------------------------- 1 | const { setup, loadConfig, get } = require('@nuxtjs/module-test-utils') 2 | 3 | describe('multiple-dirs', () => { 4 | let nuxt 5 | 6 | beforeAll(async () => { 7 | ({ nuxt } = (await setup(loadConfig(__dirname, 'multiple-dirs')))) 8 | }, 60000) 9 | 10 | afterAll(async () => { 11 | await nuxt.close() 12 | }) 13 | 14 | test('render', async () => { 15 | const html = await get('/') 16 | expect(html).toContain('Works!') 17 | expect(html).toContain('foo content') 18 | expect(html).toContain('bar content') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/multiple-suffixes.test.js: -------------------------------------------------------------------------------- 1 | const { setup, loadConfig, get } = require('@nuxtjs/module-test-utils') 2 | 3 | describe('multiple-suffixes', () => { 4 | let nuxt 5 | 6 | beforeAll(async () => { 7 | ({ nuxt } = (await setup(loadConfig(__dirname, 'multiple-suffixes')))) 8 | }, 60000) 9 | 10 | afterAll(async () => { 11 | await nuxt.close() 12 | }) 13 | 14 | test('render', async () => { 15 | const html = await get('/') 16 | expect(html).toContain('Works!') 17 | expect(html).toContain('foo content') 18 | expect(html).toContain('bar content') 19 | }) 20 | }) 21 | -------------------------------------------------------------------------------- /test/pascal.test.js: -------------------------------------------------------------------------------- 1 | const { setup, loadConfig, get } = require('@nuxtjs/module-test-utils') 2 | 3 | describe('pascal', () => { 4 | let nuxt 5 | 6 | beforeAll(async () => { 7 | ({ nuxt } = (await setup(loadConfig(__dirname, 'pascal')))) 8 | }, 60000) 9 | 10 | afterAll(async () => { 11 | await nuxt.close() 12 | }) 13 | 14 | test('render', async () => { 15 | const html = await get('/') 16 | expect(html).toContain('Works!') 17 | expect(html).toContain('bar content') 18 | expect(html).toContain('bar foo content') 19 | expect(html).toContain('foo content') 20 | expect(html).toContain('foo bar content') 21 | }) 22 | }) 23 | -------------------------------------------------------------------------------- /test/watch.test.js: -------------------------------------------------------------------------------- 1 | const { posix: { join } } = require('path') 2 | const { loadConfig, init } = require('@nuxtjs/module-test-utils') 3 | const chokidar = require('chokidar') 4 | const globby = require('globby') 5 | 6 | // Mock globby 7 | jest.mock('globby') 8 | const toGlobbyFiles = arr => arr.map(name => ({ name, path: join('/project/nuxt', name) })) 9 | globby.mockImplementation(() => toGlobbyFiles(['a.js', 'b.global.js', 'c.global.js'])) 10 | 11 | // Mock chokidar 12 | const chokidarWatchers = [] 13 | const mockWatcher = { 14 | close: jest.fn(), 15 | on (event, fn) { 16 | chokidarWatchers.push({ event, fn }) 17 | } 18 | } 19 | chokidar.watch = () => mockWatcher 20 | const callChokidarEvent = eventName => Promise.all(chokidarWatchers.map(w => w.fn(eventName))) 21 | 22 | describe('watch', () => { 23 | let nuxt, builder 24 | 25 | beforeAll(async () => { 26 | nuxt = await init(loadConfig(__dirname, 'basic', { dev: true })) 27 | builder = { 28 | generateRoutesAndFiles: jest.fn() 29 | } 30 | await nuxt.callHook('build:before', builder) 31 | }) 32 | 33 | afterAll(async () => { 34 | await nuxt.close() 35 | }) 36 | 37 | test('discover components and pass as componentOptions', () => { 38 | const plugin = nuxt.options.build.templates.find(p => p.dst.includes('global-components')) 39 | expect(plugin.options).toMatchSnapshot() 40 | }) 41 | 42 | test('watch: no rebuild if no matched files changed', async () => { 43 | builder.generateRoutesAndFiles.mockClear() 44 | await callChokidarEvent('add') 45 | expect(builder.generateRoutesAndFiles).toHaveBeenCalledTimes(0) 46 | }) 47 | 48 | test('watch:rebuild on add/remove', async () => { 49 | builder.generateRoutesAndFiles.mockClear() 50 | globby.mockImplementationOnce(() => toGlobbyFiles(['a.js', 'b.global.js'])) 51 | 52 | await callChokidarEvent('unlink') 53 | expect(builder.generateRoutesAndFiles).toHaveBeenCalledTimes(1) 54 | }) 55 | 56 | test('watch:no rebuild on other events', async () => { 57 | builder.generateRoutesAndFiles.mockClear() 58 | globby.mockImplementationOnce(() => toGlobbyFiles(['a.js', 'b.global.js'])) 59 | 60 | await callChokidarEvent('foo') 61 | expect(builder.generateRoutesAndFiles).toHaveBeenCalledTimes(0) 62 | }) 63 | }) 64 | --------------------------------------------------------------------------------