Explorar el Código

workflow: basic template explorer

Evan You hace 6 años
padre
commit
5047bc8dbe

+ 13 - 3
packages/compiler-core/src/utils.ts

@@ -20,7 +20,7 @@ import { parse } from 'acorn'
 import { walk } from 'estree-walker'
 import { TransformContext } from './transform'
 import { OPEN_BLOCK, CREATE_BLOCK, MERGE_PROPS } from './runtimeConstants'
-import { isString } from '@vue/shared'
+import { isString, isFunction } from '@vue/shared'
 import { PropsExpression } from './transforms/transformElement'
 
 // cache node requires
@@ -29,12 +29,22 @@ import { PropsExpression } from './transforms/transformElement'
 let _parse: typeof parse
 let _walk: typeof walk
 
+function loadDep(name: string) {
+  if (typeof process !== 'undefined' && isFunction(require)) {
+    return require(name)
+  } else {
+    // This is only used when we are building a dev-only build of the compiler
+    // which runs in the browser but also uses Node deps.
+    return (window as any)._deps[name]
+  }
+}
+
 export const parseJS: typeof parse = (code: string, options: any) => {
   assert(
     !__BROWSER__,
     `Expression AST analysis can only be performed in non-browser builds.`
   )
-  const parse = _parse || (_parse = require('acorn').parse)
+  const parse = _parse || (_parse = loadDep('acorn').parse)
   return parse(code, options)
 }
 
@@ -43,7 +53,7 @@ export const walkJS: typeof walk = (ast, walker) => {
     !__BROWSER__,
     `Expression AST analysis can only be performed in non-browser builds.`
   )
-  const walk = _walk || (_walk = require('estree-walker').walk)
+  const walk = _walk || (_walk = loadDep('estree-walker').walk)
   return walk(ast, walker)
 }
 

+ 1 - 0
packages/shared/package.json

@@ -1,4 +1,5 @@
 {
   "name": "@vue/shared",
+  "version": "3.0.0-alpha.1",
   "private": true
 }

+ 8 - 0
packages/template-explorer/README.md

@@ -0,0 +1,8 @@
+## Template Explorer
+
+Live explorer for template compilation output.
+
+To run:
+
+- `yarn dev template-explorer`
+- Serve project root over a local HTTP server.

+ 43 - 0
packages/template-explorer/index.html

@@ -0,0 +1,43 @@
+<link rel="stylesheet" data-name="vs/editor/editor.main" href="../../node_modules/monaco-editor/min/vs/editor/editor.main.css">
+<style>
+body {
+  margin: 0;
+}
+.editor {
+  position: absolute;
+  top: 0;
+  bottom: 0;
+  box-sizing: border-box;
+}
+#source {
+  left: 0;
+  width: 40%;
+}
+#output {
+  left: 40%;
+  width: 60%;
+}
+</style>
+
+<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/monaco-editor/min/vs/loader.js"></script>
+<script src="./dist/template-explorer.global.js"></script>
+<script>
+window._deps = {
+  acorn,
+  'estree-walker': estreeWalker
+}
+
+require.config({
+  paths: {
+    'vs': '../../node_modules/monaco-editor/min/vs'
+  }
+})
+</script>
+<script>
+require(['vs/editor/editor.main'], init /* injected by build */)
+</script>

+ 15 - 0
packages/template-explorer/package.json

@@ -0,0 +1,15 @@
+{
+  "name": "@vue/template-explorer",
+  "version": "3.0.0-alpha.1",
+  "private": true,
+  "buildOptions": {
+    "formats": [
+      "global"
+    ],
+    "env": "development",
+    "enableNonBrowserBranches": true
+  },
+  "dependencies": {
+    "monaco-editor": "^0.18.1"
+  }
+}

+ 83 - 0
packages/template-explorer/src/index.ts

@@ -0,0 +1,83 @@
+import * as m from 'monaco-editor'
+import { compile } from '@vue/compiler-dom'
+
+const self = window as any
+
+self.init = () => {
+  const monaco = (window as any).monaco as typeof m
+  const persistedContent =
+    decodeURIComponent(window.location.hash.slice(1)) ||
+    `<div>{{ foo + bar }}</div>`
+
+  self.compilerOptions = {
+    mode: 'module',
+    prefixIdentifiers: true,
+    hoistStatic: true
+  }
+
+  function compileCode(source: string): string {
+    console.clear()
+    try {
+      const { code, ast } = compile(source, self.compilerOptions)
+
+      console.log(ast)
+      return code
+    } catch (e) {
+      console.error(e)
+      return `/* See console for error */`
+    }
+  }
+
+  const sharedOptions = {
+    theme: 'vs-dark',
+    fontSize: 14,
+    wordWrap: 'on',
+    scrollBeyondLastLine: false,
+    minimap: {
+      enabled: false
+    }
+  } as const
+
+  const editor = monaco.editor.create(
+    document.getElementById('source') as HTMLElement,
+    {
+      value: persistedContent,
+      language: 'html',
+      ...sharedOptions
+    }
+  )
+
+  const model = editor.getModel()!
+
+  model.updateOptions({
+    tabSize: 2
+  })
+
+  model.onDidChangeContent(() => {
+    const src = editor.getValue()
+    window.location.hash = encodeURIComponent(src)
+    const res = compileCode(src)
+    if (res) {
+      output.setValue(res)
+    }
+  })
+
+  const output = monaco.editor.create(
+    document.getElementById('output') as HTMLElement,
+    {
+      value: compileCode(persistedContent),
+      language: 'javascript',
+      readOnly: true,
+      ...sharedOptions
+    }
+  )
+
+  output.getModel()!.updateOptions({
+    tabSize: 2
+  })
+
+  window.addEventListener('resize', () => {
+    editor.layout()
+    output.layout()
+  })
+}

+ 2 - 1
rollup.config.js

@@ -119,7 +119,8 @@ function createConfig(output, plugins = []) {
       createReplacePlugin(
         isProductionBuild,
         isBunlderESMBuild,
-        isGlobalBuild || isBrowserESMBuild
+        (isGlobalBuild || isBrowserESMBuild) &&
+          !packageOptions.enableNonBrowserBranches
       ),
       ...plugins
     ],

+ 9 - 4
scripts/bootstrap.js

@@ -9,16 +9,21 @@ const packagesDir = path.resolve(__dirname, '../packages')
 const files = fs.readdirSync(packagesDir)
 
 files.forEach(shortName => {
-  if (shortName === 'shared') {
-    return
-  }
   if (!fs.statSync(path.join(packagesDir, shortName)).isDirectory()) {
     return
   }
 
   const name = shortName === `vue` ? shortName : `@vue/${shortName}`
   const pkgPath = path.join(packagesDir, shortName, `package.json`)
-  if (args.force || !fs.existsSync(pkgPath)) {
+  const pkgExists = fs.existsSync(pkgPath)
+  if (pkgExists) {
+    const pkg = require(pkgPath)
+    if (pkg.private) {
+      return
+    }
+  }
+
+  if (args.force || !pkgExists) {
     const json = {
       name,
       version: baseVersion,

+ 5 - 1
scripts/build.js

@@ -51,12 +51,16 @@ async function build(target) {
 
   await fs.remove(`${pkgDir}/dist`)
 
+  const env =
+    (pkg.buildOptions && pkg.buildOptions.env) ||
+    (devOnly ? 'development' : 'production')
+
   await execa(
     'rollup',
     [
       '-c',
       '--environment',
-      `NODE_ENV:${devOnly ? 'development' : 'production'},` +
+      `NODE_ENV:${env},` +
         `TARGET:${target}` +
         (formats ? `,FORMATS:${formats}` : ``) +
         (args.types ? `,TYPES:true` : ``) +

+ 2 - 2
scripts/utils.js

@@ -5,7 +5,7 @@ const targets = (exports.targets = fs.readdirSync('packages').filter(f => {
     return false
   }
   const pkg = require(`../packages/${f}/package.json`)
-  if (pkg.private) {
+  if (pkg.private && !pkg.buildOptions) {
     return false
   }
   return true
@@ -26,6 +26,6 @@ exports.fuzzyMatchTarget = (partialTargets, includeAllMatching) => {
   if (matched.length) {
     return matched
   } else {
-    throw new Error(`Target ${partialTarget} not found!`)
+    throw new Error(`Target ${partialTargets} not found!`)
   }
 }

+ 2 - 1
tsconfig.json

@@ -27,7 +27,8 @@
       "@vue/reactivity": ["packages/reactivity/src"],
       "@vue/compiler-core": ["packages/compiler-core/src"],
       "@vue/compiler-dom": ["packages/compiler-dom/src"],
-      "@vue/server-renderer": ["packages/server-renderer/src"]
+      "@vue/server-renderer": ["packages/server-renderer/src"],
+      "@vue/template-explorer": ["packages/template-explorer/src"]
     }
   },
   "include": [

+ 5 - 0
yarn.lock

@@ -4932,6 +4932,11 @@ modify-values@^1.0.0:
   resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022"
   integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw==
 
+monaco-editor@^0.18.1:
+  version "0.18.1"
+  resolved "https://registry.yarnpkg.com/monaco-editor/-/monaco-editor-0.18.1.tgz#ced7c305a23109875feeaf395a504b91f6358cfc"
+  integrity sha512-fmL+RFZ2Hrezy+X/5ZczQW51LUmvzfcqOurnkCIRFTyjdVjzR7JvENzI6+VKBJzJdPh6EYL4RoWl92b2Hrk9fw==
+
 move-concurrently@^1.0.1:
   version "1.0.1"
   resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92"