]> git.ipfire.org Git - thirdparty/vuejs/core.git/commitdiff
feat(compiler-core): switch to @babel/parser for expression parsing
authorEvan You <yyx990803@gmail.com>
Thu, 27 Feb 2020 21:53:51 +0000 (16:53 -0500)
committerEvan You <yyx990803@gmail.com>
Thu, 27 Feb 2020 21:53:51 +0000 (16:53 -0500)
    This enables default support for parsing bigInt, optional chaining
    and nullish coalescing, and also adds the `expressionPlugins`
    compiler option for enabling additional parsing plugins listed at
    https://babeljs.io/docs/en/next/babel-parser#plugins.

13 files changed:
package.json
packages/compiler-core/__tests__/transforms/transformExpressions.spec.ts
packages/compiler-core/package.json
packages/compiler-core/src/errors.ts
packages/compiler-core/src/options.ts
packages/compiler-core/src/transform.ts
packages/compiler-core/src/transforms/transformExpression.ts
packages/compiler-core/src/utils.ts
packages/template-explorer/index.html
packages/template-explorer/local.html
packages/template-explorer/src/index.ts
rollup.config.js
yarn.lock

index 96c036da2cdfabb5e83ae6800100178f1d1645f4..82e828a05d0265b0827262a11cc2ddc9afb63333 100644 (file)
@@ -37,7 +37,9 @@
   },
   "devDependencies": {
     "@microsoft/api-extractor": "^7.3.9",
+    "@rollup/plugin-commonjs": "^11.0.2",
     "@rollup/plugin-json": "^4.0.0",
+    "@rollup/plugin-node-resolve": "^7.1.1",
     "@rollup/plugin-replace": "^2.2.1",
     "@types/jest": "^24.0.21",
     "@types/puppeteer": "^2.0.0",
index 6f1f280bd885a37d7dc06e67e4ae4e0efbdb23f4..0446fa2293600db447af959d79d61c38310d5c99 100644 (file)
@@ -380,7 +380,65 @@ describe('compiler: expression transform', () => {
     const onError = jest.fn()
     parseWithExpressionTransform(`{{ a( }}`, { onError })
     expect(onError.mock.calls[0][0].message).toMatch(
-      `Invalid JavaScript expression.`
+      `Error parsing JavaScript expression: Unexpected token`
     )
   })
+
+  describe('ES Proposals support', () => {
+    test('bigInt', () => {
+      const node = parseWithExpressionTransform(
+        `{{ 13000n }}`
+      ) as InterpolationNode
+      expect(node.content).toMatchObject({
+        type: NodeTypes.SIMPLE_EXPRESSION,
+        content: `13000n`,
+        isStatic: false,
+        isConstant: true
+      })
+    })
+
+    test('nullish colescing', () => {
+      const node = parseWithExpressionTransform(
+        `{{ a ?? b }}`
+      ) as InterpolationNode
+      expect(node.content).toMatchObject({
+        type: NodeTypes.COMPOUND_EXPRESSION,
+        children: [{ content: `_ctx.a` }, ` ?? `, { content: `_ctx.b` }]
+      })
+    })
+
+    test('optional chaining', () => {
+      const node = parseWithExpressionTransform(
+        `{{ a?.b?.c }}`
+      ) as InterpolationNode
+      expect(node.content).toMatchObject({
+        type: NodeTypes.COMPOUND_EXPRESSION,
+        children: [
+          { content: `_ctx.a` },
+          `?.`,
+          { content: `b` },
+          `?.`,
+          { content: `c` }
+        ]
+      })
+    })
+
+    test('Enabling additional plugins', () => {
+      // enabling pipeline operator to replace filters:
+      const node = parseWithExpressionTransform(`{{ a |> uppercase }}`, {
+        expressionPlugins: [
+          [
+            'pipelineOperator',
+            {
+              proposal: 'minimal'
+            }
+          ]
+        ]
+      }) as InterpolationNode
+      expect(node.content).toMatchObject({
+        type: NodeTypes.COMPOUND_EXPRESSION,
+        children: [{ content: `_ctx.a` }, ` |> `, { content: `_ctx.uppercase` }]
+      })
+    })
+  })
 })
index 2b14a65b9f4323525b9fca075ada7c117a32c426..e11b6e1b208e803b6f3753ef00f1579030aedaec 100644 (file)
@@ -30,7 +30,8 @@
   },
   "homepage": "https://github.com/vuejs/vue/tree/dev/packages/compiler-core#readme",
   "dependencies": {
-    "acorn": "^7.1.0",
+    "@babel/parser": "^7.8.6",
+    "@babel/types": "^7.8.6",
     "estree-walker": "^0.8.1",
     "source-map": "^0.6.1"
   }
index a46fa80e9118c77e4507fdd662a3997aab603b6c..408847a5bdc8fc06d381fdfd6cf7e6e29dfe2787 100644 (file)
@@ -16,9 +16,13 @@ export function defaultOnError(error: CompilerError) {
 export function createCompilerError<T extends number>(
   code: T,
   loc?: SourceLocation,
-  messages?: { [code: number]: string }
+  messages?: { [code: number]: string },
+  additionalMessage?: string
 ): T extends ErrorCodes ? CoreCompilerError : CompilerError {
-  const msg = __DEV__ || !__BROWSER__ ? (messages || errorMessages)[code] : code
+  const msg =
+    __DEV__ || !__BROWSER__
+      ? (messages || errorMessages)[code] + (additionalMessage || ``)
+      : code
   const error = new SyntaxError(String(msg)) as CompilerError
   error.code = code
   error.loc = loc
@@ -174,7 +178,7 @@ export const errorMessages: { [code: number]: string } = {
   [ErrorCodes.X_V_MODEL_NO_EXPRESSION]: `v-model is missing expression.`,
   [ErrorCodes.X_V_MODEL_MALFORMED_EXPRESSION]: `v-model value must be a valid JavaScript member expression.`,
   [ErrorCodes.X_V_MODEL_ON_SCOPE_VARIABLE]: `v-model cannot be used on v-for or v-slot scope variables because they are not writable.`,
-  [ErrorCodes.X_INVALID_EXPRESSION]: `Invalid JavaScript expression.`,
+  [ErrorCodes.X_INVALID_EXPRESSION]: `Error parsing JavaScript expression: `,
   [ErrorCodes.X_KEEP_ALIVE_INVALID_CHILDREN]: `<KeepAlive> expects exactly one child component.`,
 
   // generic errors
index dc9d3631e16aa976d8898a2d4f0de7a2be4fcaac..68a8e3282abc910d6d5f125f81828b611f7c49b7 100644 (file)
@@ -6,6 +6,7 @@ import {
   DirectiveTransform,
   TransformContext
 } from './transform'
+import { ParserPlugin } from '@babel/parser'
 
 export interface ParserOptions {
   isVoidTag?: (tag: string) => boolean // e.g. img, br, hr
@@ -61,6 +62,9 @@ export interface TransformOptions {
   //   analysis to determine if a handler is safe to cache.
   // - Default: false
   cacheHandlers?: boolean
+  // a list of parser plugins to enable for @babel/parser
+  // https://babeljs.io/docs/en/next/babel-parser#plugins
+  expressionPlugins?: ParserPlugin[]
   // SFC scoped styles ID
   scopeId?: string | null
   ssr?: boolean
index af62ba8675800cb0a7a2993abaef0d4f0e4c7f22..12c9023b6262d331bc8bc69db6ce2c3397fdd2b6 100644 (file)
@@ -117,6 +117,7 @@ export function createTransformContext(
     directiveTransforms = {},
     transformHoist = null,
     isBuiltInComponent = NOOP,
+    expressionPlugins = [],
     scopeId = null,
     ssr = false,
     onError = defaultOnError
@@ -131,6 +132,7 @@ export function createTransformContext(
     directiveTransforms,
     transformHoist,
     isBuiltInComponent,
+    expressionPlugins,
     scopeId,
     ssr,
     onError,
index b78daaf7226ced474717bbae67b4a4ed4a4dc0ed..b62bcefcd63a31215a8597827e102be67a975bb4 100644 (file)
@@ -16,7 +16,6 @@ import {
   CompoundExpressionNode,
   createCompoundExpression
 } from '../ast'
-import { Node, Function, Identifier, Property } from 'estree'
 import {
   advancePositionWithClone,
   isSimpleIdentifier,
@@ -25,6 +24,7 @@ import {
 } from '../utils'
 import { isGloballyWhitelisted, makeMap } from '@vue/shared'
 import { createCompilerError, ErrorCodes } from '../errors'
+import { Node, Function, Identifier, ObjectProperty } from '@babel/types'
 
 const isLiteralWhitelisted = /*#__PURE__*/ makeMap('true,false,null,this')
 
@@ -117,22 +117,39 @@ export function processExpression(
     ? ` ${rawExp} `
     : `(${rawExp})${asParams ? `=>{}` : ``}`
   try {
-    ast = parseJS(source, { ranges: true })
+    ast = parseJS(source, {
+      plugins: [
+        ...context.expressionPlugins,
+        // by default we enable proposals slated for ES2020.
+        // full list at https://babeljs.io/docs/en/next/babel-parser#plugins
+        // this will need to be updated as the spec moves forward.
+        'bigInt',
+        'optionalChaining',
+        'nullishCoalescingOperator'
+      ]
+    }).program
   } catch (e) {
     context.onError(
-      createCompilerError(ErrorCodes.X_INVALID_EXPRESSION, node.loc)
+      createCompilerError(
+        ErrorCodes.X_INVALID_EXPRESSION,
+        node.loc,
+        undefined,
+        e.message
+      )
     )
     return node
   }
 
   const ids: (Identifier & PrefixMeta)[] = []
   const knownIds = Object.create(context.identifiers)
+  const isDuplicate = (node: Node & PrefixMeta): boolean =>
+    ids.some(id => id.start === node.start)
 
   // walk the AST and look for identifiers that need to be prefixed with `_ctx.`.
   walkJS(ast, {
     enter(node: Node & PrefixMeta, parent) {
       if (node.type === 'Identifier') {
-        if (!ids.includes(node)) {
+        if (!isDuplicate(node)) {
           const needPrefix = shouldPrefix(node, parent)
           if (!knownIds[node.name] && needPrefix) {
             if (isPropertyShorthand(node, parent)) {
@@ -246,17 +263,20 @@ export function processExpression(
 const isFunction = (node: Node): node is Function =>
   /Function(Expression|Declaration)$/.test(node.type)
 
-const isPropertyKey = (node: Node, parent: Node) =>
-  parent &&
-  parent.type === 'Property' &&
-  parent.key === node &&
-  !parent.computed
+const isStaticProperty = (node: Node): node is ObjectProperty =>
+  node && node.type === 'ObjectProperty' && !node.computed
 
-const isPropertyShorthand = (node: Node, parent: Node) =>
-  isPropertyKey(node, parent) && (parent as Property).value === node
+const isPropertyShorthand = (node: Node, parent: Node) => {
+  return (
+    isStaticProperty(parent) &&
+    parent.value === node &&
+    parent.key.type === 'Identifier' &&
+    parent.key.name === (node as Identifier).name
+  )
+}
 
 const isStaticPropertyKey = (node: Node, parent: Node) =>
-  isPropertyKey(node, parent) && (parent as Property).value !== node
+  isStaticProperty(parent) && parent.key === node
 
 function shouldPrefix(identifier: Identifier, parent: Node) {
   if (
@@ -271,7 +291,8 @@ function shouldPrefix(identifier: Identifier, parent: Node) {
     !isStaticPropertyKey(identifier, parent) &&
     // not a property of a MemberExpression
     !(
-      parent.type === 'MemberExpression' &&
+      (parent.type === 'MemberExpression' ||
+        parent.type === 'OptionalMemberExpression') &&
       parent.property === identifier &&
       !parent.computed
     ) &&
index 7fe6a4985ffab6b94ab472ede6879d93674be768..2f57bcd9a01f325205220446aeadc0011a015f96 100644 (file)
@@ -22,8 +22,6 @@ import {
   InterpolationNode,
   VNodeCall
 } from './ast'
-import { parse } from 'acorn'
-import { walk } from 'estree-walker'
 import { TransformContext } from './transform'
 import {
   MERGE_PROPS,
@@ -33,6 +31,8 @@ import {
   BASE_TRANSITION
 } from './runtimeHelpers'
 import { isString, isFunction, isObject, hyphenate } from '@vue/shared'
+import { parse } from '@babel/parser'
+import { Node } from '@babel/types'
 
 export const isBuiltInType = (tag: string, expected: string): boolean =>
   tag === expected || tag === hyphenate(expected)
@@ -53,7 +53,7 @@ export function isCoreComponent(tag: string): symbol | void {
 // lazy require dependencies so that they don't end up in rollup's dep graph
 // and thus can be tree-shaken in browser builds.
 let _parse: typeof parse
-let _walk: typeof walk
+let _walk: any
 
 export function loadDep(name: string) {
   if (!__BROWSER__ && typeof process !== 'undefined' && isFunction(require)) {
@@ -70,11 +70,18 @@ export const parseJS: typeof parse = (code, options) => {
     !__BROWSER__,
     `Expression AST analysis can only be performed in non-browser builds.`
   )
-  const parse = _parse || (_parse = loadDep('acorn').parse)
-  return parse(code, options)
+  if (!_parse) {
+    _parse = loadDep('@babel/parser').parse
+  }
+  return _parse(code, options)
+}
+
+interface Walker {
+  enter?(node: Node, parent: Node): void
+  leave?(node: Node): void
 }
 
-export const walkJS: typeof walk = (ast, walker) => {
+export const walkJS = (ast: Node, walker: Walker) => {
   assert(
     !__BROWSER__,
     `Expression AST analysis can only be performed in non-browser builds.`
index f1a66e98a2005f9ca966ed6876b60db0ddeb24a3..3718421823c284269e1738fe0fd64aac225a8d4f 100644 (file)
@@ -6,14 +6,11 @@
 <div id="source" class="editor"></div>
 <div id="output" class="editor"></div>
 
-<script src="https://unpkg.com/acorn@7.1.0/dist/acorn.js"></script>
 <script src="https://unpkg.com/estree-walker@0.8.1/dist/estree-walker.umd.js"></script>
 <script src="https://unpkg.com/source-map@0.6.1/dist/source-map.js"></script>
 <script src="https://unpkg.com/monaco-editor@0.18.1/min/vs/loader.js"></script>
-<script src="./dist/template-explorer.global.js"></script>
 <script>
 window._deps = {
-  acorn,
   'estree-walker': estreeWalker,
   'source-map': sourceMap
 }
@@ -24,6 +21,7 @@ require.config({
   }
 })
 </script>
+<script src="./dist/template-explorer.global.js"></script>
 <script>
 require(['vs/editor/editor.main'], init /* injected by build */)
 </script>
index 349758adc1c55e6640f498745cdba476bcabf606..4ab1d97e80381b03ae176f2d9c91d10f451d9eb2 100644 (file)
@@ -6,14 +6,12 @@
 <div id="source" class="editor"></div>
 <div id="output" class="editor"></div>
 
-<script src="../../node_modules/acorn/dist/acorn.js"></script>
 <script src="../../node_modules/estree-walker/dist/estree-walker.umd.js"></script>
 <script src="../../node_modules/source-map/dist/source-map.js"></script>
 <script src="../../node_modules/monaco-editor/min/vs/loader.js"></script>
-<script src="./dist/template-explorer.global.js"></script>
 <script>
 window._deps = {
-  acorn,
+  // @babel/parser is injected by the bundle
   'estree-walker': estreeWalker,
   'source-map': sourceMap
 }
@@ -24,6 +22,7 @@ require.config({
   }
 })
 </script>
+<script src="./dist/template-explorer.global.js"></script>
 <script>
 require(['vs/editor/editor.main'], init /* injected by build */)
 </script>
index af90ce6c4b12289672feb55a84719e9b0edc60cb..f5579fbd6bf7ce5d6dbb5e17562015af05e7d1c1 100644 (file)
@@ -4,6 +4,9 @@ import { compile as ssrCompile } from '@vue/compiler-ssr'
 import { compilerOptions, initOptions, ssrMode } from './options'
 import { watchEffect } from '@vue/runtime-dom'
 import { SourceMapConsumer } from 'source-map'
+import { parse } from '@babel/parser'
+
+window._deps['@babel/parser'] = { parse }
 
 declare global {
   interface Window {
index b1248ee0d9bf2efa78ebc12f3acbeff530e120bc..b5150fdc630d6ec7875dfcdef117fc7b860ec3d1 100644 (file)
@@ -116,6 +116,13 @@ function createConfig(format, output, plugins = []) {
       ? []
       : knownExternals.concat(Object.keys(pkg.dependencies || []))
 
+  const nodePlugins = packageOptions.enableNonBrowserBranches
+    ? [
+        require('@rollup/plugin-node-resolve')(),
+        require('@rollup/plugin-commonjs')()
+      ]
+    : []
+
   return {
     input: resolve(entryFile),
     // Global and Browser ESM builds inlines everything so that they can be
@@ -136,6 +143,7 @@ function createConfig(format, output, plugins = []) {
         isGlobalBuild,
         isNodeBuild
       ),
+      ...nodePlugins,
       ...plugins
     ],
     output,
index 9cc7c2989b0d839cd239b436f3034b1b59ed74e8..44334f1fb0d7ea94f76140d9a5a0568e22bff69d 100644 (file)
--- a/yarn.lock
+++ b/yarn.lock
   resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.5.5.tgz#02f077ac8817d3df4a832ef59de67565e71cca4b"
   integrity sha512-E5BN68cqR7dhKan1SfqgPGhQ178bkVKpXTPEXnFJBrEt8/DKRZlybmy+IgYLTeN7tp1R5Ccmbm2rBk17sHYU3g==
 
+"@babel/parser@^7.8.6":
+  version "7.8.6"
+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c"
+  integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g==
+
 "@babel/plugin-syntax-object-rest-spread@^7.0.0":
   version "7.2.0"
   resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e"
     lodash "^4.17.13"
     to-fast-properties "^2.0.0"
 
+"@babel/types@^7.8.6":
+  version "7.8.6"
+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.6.tgz#629ecc33c2557fcde7126e58053127afdb3e6d01"
+  integrity sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA==
+  dependencies:
+    esutils "^2.0.2"
+    lodash "^4.17.13"
+    to-fast-properties "^2.0.0"
+
 "@cnakazawa/watch@^1.0.3":
   version "1.0.3"
   resolved "https://registry.yarnpkg.com/@cnakazawa/watch/-/watch-1.0.3.tgz#099139eaec7ebf07a27c1786a3ff64f39464d2ef"
     "@nodelib/fs.scandir" "2.1.1"
     fastq "^1.6.0"
 
+"@rollup/plugin-commonjs@^11.0.2":
+  version "11.0.2"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-11.0.2.tgz#837cc6950752327cb90177b608f0928a4e60b582"
+  integrity sha512-MPYGZr0qdbV5zZj8/2AuomVpnRVXRU5XKXb3HVniwRoRCreGlf5kOE081isNWeiLIi6IYkwTX9zE0/c7V8g81g==
+  dependencies:
+    "@rollup/pluginutils" "^3.0.0"
+    estree-walker "^1.0.1"
+    is-reference "^1.1.2"
+    magic-string "^0.25.2"
+    resolve "^1.11.0"
+
 "@rollup/plugin-json@^4.0.0":
   version "4.0.2"
   resolved "https://registry.yarnpkg.com/@rollup/plugin-json/-/plugin-json-4.0.2.tgz#482185ee36ac7dd21c346e2dbcc22ffed0c6f2d6"
   dependencies:
     "@rollup/pluginutils" "^3.0.4"
 
+"@rollup/plugin-node-resolve@^7.1.1":
+  version "7.1.1"
+  resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-7.1.1.tgz#8c6e59c4b28baf9d223028d0e450e06a485bb2b7"
+  integrity sha512-14ddhD7TnemeHE97a4rLOhobfYvUVcaYuqTnL8Ti7Jxi9V9Jr5LY7Gko4HZ5k4h4vqQM0gBQt6tsp9xXW94WPA==
+  dependencies:
+    "@rollup/pluginutils" "^3.0.6"
+    "@types/resolve" "0.0.8"
+    builtin-modules "^3.1.0"
+    is-module "^1.0.0"
+    resolve "^1.14.2"
+
 "@rollup/plugin-replace@^2.2.1":
   version "2.3.1"
   resolved "https://registry.yarnpkg.com/@rollup/plugin-replace/-/plugin-replace-2.3.1.tgz#16fb0563628f9e6c6ef9e05d48d3608916d466f5"
     "@rollup/pluginutils" "^3.0.4"
     magic-string "^0.25.5"
 
-"@rollup/pluginutils@^3.0.4":
+"@rollup/pluginutils@^3.0.0", "@rollup/pluginutils@^3.0.4", "@rollup/pluginutils@^3.0.6":
   version "3.0.8"
   resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-3.0.8.tgz#4e94d128d94b90699e517ef045422960d18c8fde"
   integrity sha512-rYGeAc4sxcZ+kPG/Tw4/fwJODC3IXHYDH4qusdN/b6aLw5LPUbzpecYbEJh4sVQGPFJxd2dBU4kc1H3oy9/bnw==
     "@types/bluebird" "*"
     "@types/node" "*"
 
-"@types/estree@*":
+"@types/estree@*", "@types/estree@0.0.39":
   version "0.0.39"
   resolved "https://registry.yarnpkg.com/@types/estree/-/estree-0.0.39.tgz#e177e699ee1b8c22d23174caaa7422644389509f"
   integrity sha512-EYNwp3bU+98cpU4lAWYYL7Zz+2gryWH1qbdDTidVd6hkiR6weksdbMadyXKXNPEkQFhXM+hVO9ZygomHXp+AIw==
   dependencies:
     "@types/node" "*"
 
+"@types/resolve@0.0.8":
+  version "0.0.8"
+  resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-0.0.8.tgz#f26074d238e02659e323ce1a13d041eee280e194"
+  integrity sha512-auApPaJf3NPfe18hSoJkp8EbZzer2ISk7o8mCC3M9he/a04+gbMF97NkpD2S8riMGvm4BMRI59/SZQSaLTKpsQ==
+  dependencies:
+    "@types/node" "*"
+
 "@types/stack-utils@^1.0.1":
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e"
@@ -1057,6 +1100,11 @@ builtin-modules@^1.0.0:
   resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f"
   integrity sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=
 
+builtin-modules@^3.1.0:
+  version "3.1.0"
+  resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-3.1.0.tgz#aad97c15131eb76b65b50ef208e7584cd76a7484"
+  integrity sha512-k0KL0aWZuBt2lrxrcASWDfwOLMnodeQjodT/1SxEQAXsHANgo6ZC/VEaSEHCXt7aSTZ4/4H5LKa+tBXmW7Vtvw==
+
 bytes@3.0.0:
   version "3.0.0"
   resolved "https://registry.yarnpkg.com/bytes/-/bytes-3.0.0.tgz#d32815404d689699f85a4ea4fa8755dd13a96048"
@@ -3003,6 +3051,11 @@ is-installed-globally@^0.1.0:
     global-dirs "^0.1.0"
     is-path-inside "^1.0.0"
 
+is-module@^1.0.0:
+  version "1.0.0"
+  resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591"
+  integrity sha1-Mlj7afeMFNW4FdZkM2tM/7ZEFZE=
+
 is-npm@^1.0.0:
   version "1.0.0"
   resolved "https://registry.yarnpkg.com/is-npm/-/is-npm-1.0.0.tgz#f2fb63a65e4905b406c86072765a1a4dc793b9f4"
@@ -3080,6 +3133,13 @@ is-redirect@^1.0.0:
   resolved "https://registry.yarnpkg.com/is-redirect/-/is-redirect-1.0.0.tgz#1d03dded53bd8db0f30c26e4f95d36fc7c87dc24"
   integrity sha1-HQPd7VO9jbDzDCbk+V02/HyH3CQ=
 
+is-reference@^1.1.2:
+  version "1.1.4"
+  resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.1.4.tgz#3f95849886ddb70256a3e6d062b1a68c13c51427"
+  integrity sha512-uJA/CDPO3Tao3GTrxYn6AwkM4nUPJiGGYu5+cB8qbC7WGFlrKZbiRo7SFKxUAEpFUfiHofWCXBUNhvYJMh+6zw==
+  dependencies:
+    "@types/estree" "0.0.39"
+
 is-regex@^1.0.3, is-regex@^1.0.4:
   version "1.0.4"
   resolved "https://registry.yarnpkg.com/is-regex/-/is-regex-1.0.4.tgz#5517489b547091b0930e095654ced25ee97e9491"
@@ -3993,7 +4053,7 @@ lru-cache@^5.1.1:
   dependencies:
     yallist "^3.0.2"
 
-magic-string@^0.25.5:
+magic-string@^0.25.2, magic-string@^0.25.5:
   version "0.25.6"
   resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.25.6.tgz#5586387d1242f919c6d223579cc938bf1420795e"
   integrity sha512-3a5LOMSGoCTH5rbqobC2HuDNRtE2glHZ8J7pK+QZYppyWA36yuNpsX994rIY2nCuyP7CZYy7lQq/X2jygiZ89g==
@@ -5381,6 +5441,13 @@ resolve@1.x, resolve@^1.1.6, resolve@^1.10.0, resolve@^1.3.2:
   dependencies:
     path-parse "^1.0.6"
 
+resolve@^1.11.0, resolve@^1.14.2:
+  version "1.15.1"
+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.15.1.tgz#27bdcdeffeaf2d6244b95bb0f9f4b4653451f3e8"
+  integrity sha512-84oo6ZTtoTUpjgNEr5SJyzQhzL72gaRodsSfyxC/AXRvwu0Yse9H8eF9IpGo7b8YetZhlI6v7ZQ6bKBFV/6S7w==
+  dependencies:
+    path-parse "^1.0.6"
+
 restore-cursor@^2.0.0:
   version "2.0.0"
   resolved "https://registry.yarnpkg.com/restore-cursor/-/restore-cursor-2.0.0.tgz#9f7ee287f82fd326d4fd162923d62129eee0dfaf"