diff --git a/.eslintrc.js b/.eslintrc.js
index 3229de98d..d0c0c0793 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -71,6 +71,18 @@ module.exports = {
'no-proto': 2,
'no-redeclare': 2,
'no-regex-spaces': 2,
+ 'no-restricted-imports': [
+ 'error',
+ {
+ paths: [
+ '@vue/reactivity',
+ '@vue/runtime-core',
+ '@vue/runtime-dom',
+ '@vue/shared'
+ ],
+ message: "Please always import these APIs from the main 'vue' package"
+ }
+ ],
'no-return-assign': [2, 'except-parens'],
'no-self-assign': 2,
'no-self-compare': 2,
diff --git a/docs/rules/no-restricted-imports.md b/docs/rules/no-restricted-imports.md
new file mode 100644
index 000000000..c763d2c15
--- /dev/null
+++ b/docs/rules/no-restricted-imports.md
@@ -0,0 +1,42 @@
+---
+pageClass: rule-details
+sidebarDepth: 0
+title: vue/no-restricted-imports
+description: disallow imports from some `'@vue/*'` packages
+---
+# vue/no-restricted-imports
+
+> disallow imports from some `'@vue/*'` packages
+
+- :exclamation: ***This rule has not been released yet.***
+
+## :book: Further Reading
+
+- [no-restricted-imports]
+
+[no-restricted-imports]: https://eslint.org/docs/rules/no-restricted-imports
+
+
+
+```vue
+
+```
+
+
+
+## :rocket: Version
+
+This rule was introduced in eslint-plugin-vue v*.0.0
+
+## :mag: Implementation
+
+- [Rule source](https://github.com/vuejs/eslint-plugin-vue/blob/master/lib/rules/no-restricted-imports.js)
+- [Test source](https://github.com/vuejs/eslint-plugin-vue/blob/master/tests/lib/rules/no-restricted-imports.js)
+
+Taken with ❤️ [from ESLint core](https://eslint.org/docs/rules/no-restricted-imports)
\ No newline at end of file
diff --git a/lib/rules/no-restricted-imports.js b/lib/rules/no-restricted-imports.js
new file mode 100644
index 000000000..662caf6dd
--- /dev/null
+++ b/lib/rules/no-restricted-imports.js
@@ -0,0 +1,12 @@
+/**
+ * @author Jackson Hammond
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+const { wrapCoreRule } = require('../utils')
+
+// eslint-disable-next-line no-invalid-meta, no-invalid-meta-docs-categories
+module.exports = wrapCoreRule('no-restricted-imports', {
+ applyDocument: true
+})
diff --git a/tests/lib/rules/no-restricted-imports.js b/tests/lib/rules/no-restricted-imports.js
new file mode 100644
index 000000000..862446571
--- /dev/null
+++ b/tests/lib/rules/no-restricted-imports.js
@@ -0,0 +1,57 @@
+/**
+ * @author Jackson Hammond
+ * See LICENSE file in root directory for full license.
+ */
+'use strict'
+
+const RuleTester = require('eslint').RuleTester
+const rule = require('../../../lib/rules/no-restricted-imports')
+
+const tester = new RuleTester({
+ parser: require.resolve('vue-eslint-parser'),
+ parserOptions: {
+ ecmaVersion: 2020,
+ // sourceType: 'module'
+ }
+})
+
+tester.run('no-transitive-dependency-imports', rule, {
+ valid: [
+ {
+ filename: 'test.vue',
+ code: `
+ import { ref } from 'vue'
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import { ref, computed } from 'vue'
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {
+ ref
+ } from 'vue'
+ `
+ },
+ {
+ filename: 'test.vue',
+ code: `
+ import {
+ ref,
+ computed
+ } from 'vue'
+ `
+ }
+ ],
+ invalid: [
+ {
+ filename: 'test.vue',
+ code: `import { computed } from '@vue/reactivity'`,
+ errors: ["Please always import these APIs from the main 'vue' package"]
+ }
+ ]
+})