import fs from 'fs' import path from 'path' import { transformSync } from '@babel/core' import { parseComponent, compileTemplate } from 'vue/compiler-sfc' // 沿用项目的 Vue 2.7 SFC 测试方式,避免调用不匹配的旧 vue-jest 编译器。 const cache = new Map() export function load(filename) { if (cache.has(filename)) return cache.get(filename) const parts = parseComponent(fs.readFileSync(filename, 'utf8')) const code = transformSync(parts.script.content, { babelrc: false, configFile: false, plugins: [require.resolve('@babel/plugin-transform-modules-commonjs')] }).code const module = { exports: {}} const localRequire = id => { if (id.startsWith('.') || id.startsWith('@/')) { let resolved = id.startsWith('.') ? path.resolve(path.dirname(filename), id) : path.resolve('src', id.slice(2)) if (fs.existsSync(resolved) && fs.statSync(resolved).isDirectory()) resolved = path.join(resolved, 'index.js') else if (!path.extname(resolved)) resolved += '.js' return resolved.endsWith('.vue') ? load(resolved) : require(resolved) } return require(id) } new Function('require', 'module', 'exports', code)(localRequire, module, module.exports) const compiled = compileTemplate({ source: parts.template.content, filename }) if (compiled.errors.length) throw new Error(compiled.errors.join('\n')) Object.assign(module.exports.default, new Function(compiled.code + ';return { render, staticRenderFns }')()) cache.set(filename, module.exports.default) return module.exports.default }