Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add vue/no-export-in-script-setup rule #1559

Merged
merged 2 commits into from Jul 6, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions docs/rules/README.md
Expand Up @@ -301,6 +301,7 @@ For example:
| [vue/no-deprecated-v-is](./no-deprecated-v-is.md) | disallow deprecated `v-is` directive (in Vue.js 3.1.0+) | :wrench: |
| [vue/no-duplicate-attr-inheritance](./no-duplicate-attr-inheritance.md) | enforce `inheritAttrs` to be set to `false` when using `v-bind="$attrs"` | |
| [vue/no-empty-component-block](./no-empty-component-block.md) | disallow the `<template>` `<script>` `<style>` block to be empty | |
| [vue/no-export-in-script-setup](./no-export-in-script-setup.md) | disallow `export` in `<script setup>` | |
| [vue/no-invalid-model-keys](./no-invalid-model-keys.md) | require valid keys in model option | |
| [vue/no-multiple-objects-in-class](./no-multiple-objects-in-class.md) | disallow to pass multiple objects into array to class | |
| [vue/no-potential-component-option-typo](./no-potential-component-option-typo.md) | disallow a potential typo in your component property | |
Expand Down
55 changes: 55 additions & 0 deletions docs/rules/no-export-in-script-setup.md
@@ -0,0 +1,55 @@
---
pageClass: rule-details
sidebarDepth: 0
title: vue/no-export-in-script-setup
description: disallow `export` in `<script setup>`
---
# vue/no-export-in-script-setup

> disallow `export` in `<script setup>`

- :exclamation: <badge text="This rule has not been released yet." vertical="middle" type="error"> ***This rule has not been released yet.*** </badge>

## :book: Rule Details

This rule warns ES module exports in `<script setup>`.

The previous version of `<script setup>` RFC used `export` to define variables used in templates, but the new `<script setup>` RFC has been updated to define without using `export`.
See [Vue RFCs - 0040-script-setup] for more details.

<eslint-code-block :rules="{'vue/no-export-in-script-setup': ['error']}">

```vue
<script setup>
/* ✓ GOOD */
let msg = 'Hello!'
</script>
```

</eslint-code-block>

<eslint-code-block :rules="{'vue/no-export-in-script-setup': ['error']}">

```vue
<script setup>
/* ✗ BAD */
export let msg = 'Hello!'
</script>
```

</eslint-code-block>

## :wrench: Options

Nothing.

## :books: Further Reading

- [Vue RFCs - 0040-script-setup]

[Vue RFCs - 0040-script-setup]: https://github.com/vuejs/rfcs/blob/master/active-rfcs/0040-script-setup.md

## :mag: Implementation

- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-export-in-script-setup.js)
- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-export-in-script-setup.js)
2 changes: 2 additions & 0 deletions docs/user-guide/README.md
Expand Up @@ -103,6 +103,8 @@ If you want to use custom parsers such as [babel-eslint](https://www.npmjs.com/p
}
```

The `parserOptions.parser` option can also specify an object to specify multiple parsers. See [vue-eslint-parser README](https://github.com/vuejs/vue-eslint-parser#readme) for more details.

### How does ESLint detect components?

All component-related rules are applied to code that passes any of the following checks:
Expand Down
1 change: 1 addition & 0 deletions lib/index.js
Expand Up @@ -81,6 +81,7 @@ module.exports = {
'no-duplicate-attributes': require('./rules/no-duplicate-attributes'),
'no-empty-component-block': require('./rules/no-empty-component-block'),
'no-empty-pattern': require('./rules/no-empty-pattern'),
'no-export-in-script-setup': require('./rules/no-export-in-script-setup'),
'no-extra-parens': require('./rules/no-extra-parens'),
'no-invalid-model-keys': require('./rules/no-invalid-model-keys'),
'no-irregular-whitespace': require('./rules/no-irregular-whitespace'),
Expand Down
41 changes: 41 additions & 0 deletions lib/rules/no-export-in-script-setup.js
@@ -0,0 +1,41 @@
/**
* @author Yosuke Ota
* See LICENSE file in root directory for full license.
*/
'use strict'

const utils = require('../utils')

module.exports = {
meta: {
type: 'problem',
docs: {
description: 'disallow `export` in `<script setup>`',
// TODO Switch in the major version.
// categories: ['vue3-essential'],
categories: undefined,
url: 'https://eslint.vuejs.org/rules/no-export-in-script-setup.html'
},
fixable: null,
schema: [],
messages: {
forbidden: '`<script setup>` cannot contain ES module exports.'
}
},
/** @param {RuleContext} context */
create(context) {
/** @param {ExportAllDeclaration | ExportDefaultDeclaration | ExportNamedDeclaration} node */
function report(node) {
context.report({
node,
messageId: 'forbidden'
})
}

return utils.defineScriptSetupVisitor(context, {
ExportAllDeclaration: report,
ExportDefaultDeclaration: report,
ExportNamedDeclaration: report
})
}
}
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -56,7 +56,7 @@
"eslint-utils": "^2.1.0",
"natural-compare": "^1.4.0",
"semver": "^7.3.2",
"vue-eslint-parser": "^7.7.2"
"vue-eslint-parser": "^7.8.0"
},
"devDependencies": {
"@types/eslint": "^7.2.0",
Expand Down
107 changes: 107 additions & 0 deletions tests/lib/rules/no-export-in-script-setup.js
@@ -0,0 +1,107 @@
/**
* @author Yosuke Ota
* See LICENSE file in root directory for full license.
*/
'use strict'

// ------------------------------------------------------------------------------
// Requirements
// ------------------------------------------------------------------------------

const eslint = require('eslint')
const rule = require('../../../lib/rules/no-export-in-script-setup')

const RuleTester = eslint.RuleTester
const ruleTester = new RuleTester({
parser: require.resolve('vue-eslint-parser'),
parserOptions: {
ecmaVersion: 6,
sourceType: 'module'
}
})

// ------------------------------------------------------------------------------
// Tests
// ------------------------------------------------------------------------------

ruleTester.run('no-export-in-script-setup', rule, {
valid: [
{
filename: 'test.vue',
code: `
<script>
export * from 'foo'
export default {}
export class A {}
</script>
`
},
{
filename: 'test.vue',
code: `
<script>
export * from 'foo'
export default {}
export class A {}
</script>
<script setup>
let foo;
</script>
`
}
],

invalid: [
{
filename: 'test.vue',
code: `
<script setup>
export * from 'foo'
export default {}
export class A {}
</script>
`,
errors: [
{
message: '`<script setup>` cannot contain ES module exports.',
line: 3
},
{
message: '`<script setup>` cannot contain ES module exports.',
line: 4
},
{
message: '`<script setup>` cannot contain ES module exports.',
line: 5
}
]
},
{
filename: 'test.vue',
code: `
<script>
let foo;
</script>
<script setup>
export * from 'foo'
export default {}
export class A {}
</script>
`,
errors: [
{
message: '`<script setup>` cannot contain ES module exports.',
line: 6
},
{
message: '`<script setup>` cannot contain ES module exports.',
line: 7
},
{
message: '`<script setup>` cannot contain ES module exports.',
line: 8
}
]
}
]
})