mirror of
https://github.com/element-plus/element-plus.git
synced 2025-02-17 11:49:41 +08:00
feat(build): upgrade rollup-plugin-vue (#563)
This commit is contained in:
parent
bdd287770a
commit
9a3d2911d7
@ -4,7 +4,7 @@ const path = require('path')
|
||||
const { getPackages } = require('@lerna/project')
|
||||
const css = require('rollup-plugin-css-only')
|
||||
const { nodeResolve } = require('@rollup/plugin-node-resolve')
|
||||
const vue = require('./plugin.js')
|
||||
const vue = require('rollup-plugin-vue')
|
||||
const rollup = require('rollup')
|
||||
const typescript = require('rollup-plugin-typescript2')
|
||||
|
||||
@ -17,7 +17,6 @@ const runBuild = async () => {
|
||||
.map(pkg => pkg.name)
|
||||
.filter(name =>
|
||||
name.includes('@element-plus') &&
|
||||
!name.includes('transition') &&
|
||||
!name.includes('utils'),
|
||||
).slice(process.argv[2], process.argv[3])
|
||||
|
||||
|
479
build/plugin.js
479
build/plugin.js
@ -1,479 +0,0 @@
|
||||
/* eslint-disable */
|
||||
'use strict'
|
||||
var __importDefault = (this && this.__importDefault) || function (mod) {
|
||||
return (mod && mod.__esModule) ? mod : { 'default': mod }
|
||||
}
|
||||
Object.defineProperty(exports, '__esModule', { value: true })
|
||||
try {
|
||||
require.resolve('@vue/compiler-sfc')
|
||||
}
|
||||
catch (e) {
|
||||
throw new Error('rollup-plugin-vue requires @vue/compiler-sfc to be present in the dependency ' +
|
||||
'tree.')
|
||||
}
|
||||
const compiler_sfc_1 = require('@vue/compiler-sfc')
|
||||
const fs_1 = __importDefault(require('fs'))
|
||||
const debug_1 = __importDefault(require('debug'))
|
||||
const hash_sum_1 = __importDefault(require('hash-sum'))
|
||||
const path_1 = require('path')
|
||||
const querystring_1 = __importDefault(require('querystring'))
|
||||
const rollup_pluginutils_1 = require('rollup-pluginutils')
|
||||
const debug = debug_1.default('rollup-plugin-vue')
|
||||
const defaultOptions = {
|
||||
include: /\.vue$/,
|
||||
exclude: [],
|
||||
target: 'browser',
|
||||
exposeFilename: false,
|
||||
customBlocks: [],
|
||||
}
|
||||
function PluginVue(userOptions = {}) {
|
||||
const options = {
|
||||
...defaultOptions,
|
||||
...userOptions,
|
||||
}
|
||||
const isServer = options.target === 'node'
|
||||
const isProduction = process.env.NODE_ENV === 'production' || process.env.BUILD === 'production'
|
||||
const rootContext = process.cwd()
|
||||
const filter = rollup_pluginutils_1.createFilter(options.include, options.exclude)
|
||||
const filterCustomBlock = createCustomBlockFilter(options.customBlocks)
|
||||
return {
|
||||
name: 'vue',
|
||||
async resolveId(id, importer) {
|
||||
const query = parseVuePartRequest(id)
|
||||
if (query.vue) {
|
||||
if (query.src) {
|
||||
const resolved = await this.resolve(query.filename, importer, {
|
||||
skipSelf: true,
|
||||
})
|
||||
if (resolved) {
|
||||
cache.set(resolved.id, getDescriptor(importer))
|
||||
const [, originalQuery] = id.split('?', 2)
|
||||
resolved.id += `?${originalQuery}`
|
||||
return resolved
|
||||
}
|
||||
}
|
||||
else if (!filter(query.filename)) {
|
||||
return undefined
|
||||
}
|
||||
debug(`resolveId(${id})`)
|
||||
return id
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
load(id) {
|
||||
const query = parseVuePartRequest(id)
|
||||
if (query.vue) {
|
||||
if (query.src) {
|
||||
return fs_1.default.readFileSync(query.filename, 'utf-8')
|
||||
}
|
||||
const descriptor = getDescriptor(query.filename)
|
||||
if (descriptor) {
|
||||
const block = query.type === 'template'
|
||||
? descriptor.template
|
||||
: query.type === 'script'
|
||||
? descriptor.script
|
||||
: query.type === 'style'
|
||||
? descriptor.styles[query.index]
|
||||
: typeof query.index === 'number'
|
||||
? descriptor.customBlocks[query.index]
|
||||
: null
|
||||
if (block) {
|
||||
return {
|
||||
code: block.content,
|
||||
map: normalizeSourceMap(block.map, id),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return undefined
|
||||
},
|
||||
async transform(code, id) {
|
||||
const query = parseVuePartRequest(id)
|
||||
if (query.vue) {
|
||||
if (!query.src && !filter(query.filename))
|
||||
return null
|
||||
const descriptor = getDescriptor(query.filename)
|
||||
const hasScoped = descriptor.styles.some(s => s.scoped)
|
||||
if (query.src) {
|
||||
this.addWatchFile(query.filename)
|
||||
}
|
||||
if (query.type === 'template') {
|
||||
debug(`transform(${id})`)
|
||||
const block = descriptor.template
|
||||
const preprocessLang = block.lang
|
||||
const preprocessOptions = preprocessLang &&
|
||||
options.templatePreprocessOptions &&
|
||||
options.templatePreprocessOptions[preprocessLang]
|
||||
const result = compiler_sfc_1.compileTemplate({
|
||||
filename: query.filename,
|
||||
source: code,
|
||||
inMap: query.src ? undefined : block.map,
|
||||
preprocessLang,
|
||||
preprocessOptions,
|
||||
preprocessCustomRequire: options.preprocessCustomRequire,
|
||||
compiler: options.compiler,
|
||||
ssr: isServer,
|
||||
compilerOptions: {
|
||||
...options.compilerOptions,
|
||||
scopeId: hasScoped ? `data-v-${query.id}` : undefined,
|
||||
bindingMetadata: descriptor.script
|
||||
? descriptor.script.bindings
|
||||
: undefined,
|
||||
},
|
||||
transformAssetUrls: options.transformAssetUrls,
|
||||
})
|
||||
if (result.errors.length) {
|
||||
result.errors.forEach(error => this.error(typeof error === 'string'
|
||||
? { id: query.filename, message: error }
|
||||
: createRollupError(query.filename, error)))
|
||||
return null
|
||||
}
|
||||
if (result.tips.length) {
|
||||
result.tips.forEach(tip => this.warn({
|
||||
id: query.filename,
|
||||
message: tip,
|
||||
}))
|
||||
}
|
||||
return {
|
||||
code: result.code,
|
||||
map: normalizeSourceMap(result.map, id),
|
||||
}
|
||||
}
|
||||
else if (query.type === 'style') {
|
||||
debug(`transform(${id})`)
|
||||
const block = descriptor.styles[query.index]
|
||||
let preprocessOptions = options.preprocessOptions || {}
|
||||
const preprocessLang = (options.preprocessStyles
|
||||
? block.lang
|
||||
: undefined)
|
||||
if (preprocessLang) {
|
||||
preprocessOptions =
|
||||
preprocessOptions[preprocessLang] || preprocessOptions
|
||||
// include node_modules for imports by default
|
||||
switch (preprocessLang) {
|
||||
case 'scss':
|
||||
case 'sass':
|
||||
preprocessOptions = {
|
||||
includePaths: ['node_modules'],
|
||||
...preprocessOptions,
|
||||
}
|
||||
break
|
||||
case 'less':
|
||||
case 'stylus':
|
||||
preprocessOptions = {
|
||||
paths: ['node_modules'],
|
||||
...preprocessOptions,
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
preprocessOptions = {}
|
||||
}
|
||||
const result = await compiler_sfc_1.compileStyleAsync({
|
||||
filename: query.filename,
|
||||
id: `data-v-${query.id}`,
|
||||
source: code,
|
||||
scoped: block.scoped,
|
||||
vars: !!block.vars,
|
||||
modules: !!block.module,
|
||||
postcssOptions: options.postcssOptions,
|
||||
postcssPlugins: options.postcssPlugins,
|
||||
modulesOptions: options.cssModulesOptions,
|
||||
preprocessLang,
|
||||
preprocessCustomRequire: options.preprocessCustomRequire,
|
||||
preprocessOptions,
|
||||
})
|
||||
if (result.errors.length) {
|
||||
result.errors.forEach(error => this.error({
|
||||
id: query.filename,
|
||||
message: error.message,
|
||||
}))
|
||||
return null
|
||||
}
|
||||
if (query.module) {
|
||||
return {
|
||||
code: `export default ${_(result.modules)}`,
|
||||
map: null,
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {
|
||||
code: result.code,
|
||||
map: normalizeSourceMap(result.map, id),
|
||||
}
|
||||
}
|
||||
}
|
||||
return null
|
||||
}
|
||||
else if (filter(id)) {
|
||||
debug(`transform(${id})`)
|
||||
const { descriptor, errors } = parseSFC(code, id, rootContext)
|
||||
if (errors.length) {
|
||||
errors.forEach(error => this.error(createRollupError(id, error)))
|
||||
return null
|
||||
}
|
||||
// module id for scoped CSS & hot-reload
|
||||
const output = transformVueSFC(code, id, descriptor, { rootContext, isProduction, isServer, filterCustomBlock }, options)
|
||||
debug('transient .vue file:', '\n' + output + '\n')
|
||||
return {
|
||||
code: output,
|
||||
map: {
|
||||
mappings: '',
|
||||
},
|
||||
}
|
||||
}
|
||||
else {
|
||||
return null
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
exports.default = PluginVue
|
||||
function createCustomBlockFilter(queries) {
|
||||
if (!queries || queries.length === 0)
|
||||
return () => false
|
||||
const allowed = new Set(queries.filter(query => /^[a-z]/i.test(query)))
|
||||
const disallowed = new Set(queries
|
||||
.filter(query => /^![a-z]/i.test(query))
|
||||
.map(query => query.substr(1)))
|
||||
const allowAll = queries.includes('*') || !queries.includes('!*')
|
||||
return type => {
|
||||
if (allowed.has(type))
|
||||
return true
|
||||
if (disallowed.has(type))
|
||||
return true
|
||||
return allowAll
|
||||
}
|
||||
}
|
||||
function parseVuePartRequest(id) {
|
||||
const [filename, query] = id.split('?', 2)
|
||||
if (!query)
|
||||
return { vue: false, filename }
|
||||
const raw = querystring_1.default.parse(query)
|
||||
if ('vue' in raw) {
|
||||
return {
|
||||
...raw,
|
||||
filename,
|
||||
vue: true,
|
||||
index: Number(raw.index),
|
||||
src: 'src' in raw,
|
||||
scoped: 'scoped' in raw,
|
||||
}
|
||||
}
|
||||
return { vue: false, filename }
|
||||
}
|
||||
const cache = new Map()
|
||||
function getDescriptor(id) {
|
||||
if (cache.has(id)) {
|
||||
return cache.get(id)
|
||||
}
|
||||
throw new Error(`${id} is not parsed yet`)
|
||||
}
|
||||
function parseSFC(code, id, sourceRoot) {
|
||||
const { descriptor, errors } = compiler_sfc_1.parse(code, {
|
||||
sourceMap: true,
|
||||
filename: id,
|
||||
sourceRoot: sourceRoot,
|
||||
})
|
||||
cache.set(id, descriptor)
|
||||
return { descriptor, errors: errors }
|
||||
}
|
||||
function transformVueSFC(code, resourcePath, descriptor, { rootContext, isProduction, isServer, filterCustomBlock }, options) {
|
||||
const shortFilePath = path_1.relative(rootContext, resourcePath)
|
||||
.replace(/^(\.\.[\/\\])+/, '')
|
||||
.replace(/\\/g, '/')
|
||||
const id = hash_sum_1.default(isProduction ? shortFilePath + '\n' + code : shortFilePath)
|
||||
// feature information
|
||||
const hasScoped = descriptor.styles.some(s => s.scoped)
|
||||
const templateImport = !descriptor.template
|
||||
? ''
|
||||
: getTemplateCode(descriptor, resourcePath, id, hasScoped, isServer)
|
||||
const renderReplace = !descriptor.template
|
||||
? ''
|
||||
: isServer
|
||||
? `script.ssrRender = ssrRender`
|
||||
: `script.render = render`
|
||||
const scriptImport = getScriptCode(descriptor, resourcePath)
|
||||
const stylesCode = getStyleCode(descriptor, resourcePath, id, options.preprocessStyles)
|
||||
const customBlocksCode = getCustomBlock(descriptor, resourcePath, filterCustomBlock)
|
||||
const output = [
|
||||
scriptImport,
|
||||
templateImport,
|
||||
stylesCode,
|
||||
customBlocksCode,
|
||||
renderReplace,
|
||||
]
|
||||
if (hasScoped) {
|
||||
output.push(`script.__scopeId = ${_(`data-v-${id}`)}`)
|
||||
}
|
||||
if (!isProduction) {
|
||||
output.push(`script.__file = ${_(shortFilePath)}`)
|
||||
}
|
||||
else if (options.exposeFilename) {
|
||||
output.push(`script.__file = ${_(path_1.basename(shortFilePath))}`)
|
||||
}
|
||||
output.push('export default script')
|
||||
return output.join('\n')
|
||||
}
|
||||
function getTemplateCode(descriptor, resourcePath, id, hasScoped, isServer) {
|
||||
const renderFnName = isServer ? 'ssrRender' : 'render'
|
||||
let templateImport = `const ${renderFnName} = () => {}`
|
||||
let templateRequest
|
||||
if (descriptor.template) {
|
||||
const src = descriptor.template.src || resourcePath
|
||||
const idQuery = `&id=${id}`
|
||||
const scopedQuery = hasScoped ? `&scoped=true` : ``
|
||||
const srcQuery = descriptor.template.src ? `&src` : ``
|
||||
const attrsQuery = attrsToQuery(descriptor.template.attrs, 'js', true)
|
||||
const query = `?vue&type=template${idQuery}${srcQuery}${scopedQuery}${attrsQuery}`
|
||||
templateRequest = _(src + query)
|
||||
templateImport = `import { ${renderFnName} } from ${templateRequest}`
|
||||
}
|
||||
return templateImport
|
||||
}
|
||||
function getScriptCode(descriptor, resourcePath) {
|
||||
let scriptImport = `const script = {}`
|
||||
if (descriptor.script || descriptor.scriptSetup) {
|
||||
if (compiler_sfc_1.compileScript) {
|
||||
descriptor.script = compiler_sfc_1.compileScript(descriptor)
|
||||
}
|
||||
if (descriptor.script) {
|
||||
const src = descriptor.script.src || resourcePath
|
||||
const attrsQuery = attrsToQuery(descriptor.script.attrs, 'js')
|
||||
const srcQuery = descriptor.script.src ? `&src` : ``
|
||||
const query = `?vue&type=script${srcQuery}${attrsQuery}`
|
||||
const scriptRequest = _(src + query)
|
||||
scriptImport =
|
||||
`import script from ${scriptRequest}\n` +
|
||||
`export * from ${scriptRequest}` // support named exports
|
||||
}
|
||||
}
|
||||
return scriptImport
|
||||
}
|
||||
function getStyleCode(descriptor, resourcePath, id, preprocessStyles) {
|
||||
let stylesCode = ``
|
||||
let hasCSSModules = false
|
||||
if (descriptor.styles.length) {
|
||||
descriptor.styles.forEach((style, i) => {
|
||||
const src = style.src || resourcePath
|
||||
// do not include module in default query, since we use it to indicate
|
||||
// that the module needs to export the modules json
|
||||
const attrsQuery = attrsToQuery(style.attrs, 'css', preprocessStyles)
|
||||
const attrsQueryWithoutModule = attrsQuery.replace(/&module(=true|=[^&]+)?/, '')
|
||||
// make sure to only pass id when necessary so that we don't inject
|
||||
// duplicate tags when multiple components import the same css file
|
||||
const idQuery = style.scoped ? `&id=${id}` : ``
|
||||
const srcQuery = style.src ? `&src` : ``
|
||||
const query = `?vue&type=style&index=${i}${srcQuery}${idQuery}`
|
||||
const styleRequest = src + query + attrsQuery
|
||||
const styleRequestWithoutModule = src + query + attrsQueryWithoutModule
|
||||
if (style.module) {
|
||||
if (!hasCSSModules) {
|
||||
stylesCode += `\nconst cssModules = script.__cssModules = {}`
|
||||
hasCSSModules = true
|
||||
}
|
||||
stylesCode += genCSSModulesCode(id, i, styleRequest, styleRequestWithoutModule, style.module)
|
||||
}
|
||||
else {
|
||||
stylesCode += `\nimport ${_(styleRequest)}`
|
||||
}
|
||||
// TODO SSR critical CSS collection
|
||||
})
|
||||
}
|
||||
return stylesCode
|
||||
}
|
||||
function getCustomBlock(descriptor, resourcePath, filter) {
|
||||
let code = ''
|
||||
descriptor.customBlocks.forEach((block, index) => {
|
||||
if (filter(block.type)) {
|
||||
const src = block.src || resourcePath
|
||||
const attrsQuery = attrsToQuery(block.attrs, block.type)
|
||||
const srcQuery = block.src ? `&src` : ``
|
||||
const query = `?vue&type=${block.type}&index=${index}${srcQuery}${attrsQuery}`
|
||||
const request = _(src + query)
|
||||
code += `import block${index} from ${request}\n`
|
||||
code += `if (typeof block${index} === 'function') block${index}(script)\n`
|
||||
}
|
||||
})
|
||||
return code
|
||||
}
|
||||
function createRollupError(id, error) {
|
||||
if ('code' in error) {
|
||||
return {
|
||||
id,
|
||||
plugin: 'vue',
|
||||
pluginCode: String(error.code),
|
||||
message: error.message,
|
||||
frame: error.loc.source,
|
||||
parserError: error,
|
||||
loc: error.loc
|
||||
? {
|
||||
file: id,
|
||||
line: error.loc.start.line,
|
||||
column: error.loc.start.column,
|
||||
}
|
||||
: undefined,
|
||||
}
|
||||
}
|
||||
else {
|
||||
return {
|
||||
id,
|
||||
plugin: 'vue',
|
||||
message: error.message,
|
||||
parserError: error,
|
||||
}
|
||||
}
|
||||
}
|
||||
// these are built-in query parameters so should be ignored
|
||||
// if the user happen to add them as attrs
|
||||
const ignoreList = ['id', 'index', 'src', 'type', 'lang']
|
||||
function attrsToQuery(attrs, langFallback, forceLangFallback = false) {
|
||||
let query = ``
|
||||
for (const name in attrs) {
|
||||
const value = attrs[name]
|
||||
if (!ignoreList.includes(name)) {
|
||||
query += `&${querystring_1.default.escape(name)}${value ? `=${querystring_1.default.escape(String(value))}` : ``}`
|
||||
}
|
||||
}
|
||||
if (langFallback || attrs.lang) {
|
||||
query +=
|
||||
`lang` in attrs
|
||||
? forceLangFallback
|
||||
? `&lang.${langFallback}`
|
||||
: `&lang.${attrs.lang}`
|
||||
: `&lang.${langFallback}`
|
||||
}
|
||||
return query
|
||||
}
|
||||
function _(any) {
|
||||
return JSON.stringify(any)
|
||||
}
|
||||
function normalizeSourceMap(map, id) {
|
||||
if (!map)
|
||||
return null
|
||||
if (!id.includes('type=script')) {
|
||||
map.file = id
|
||||
map.sources[0] = id
|
||||
}
|
||||
return {
|
||||
...map,
|
||||
version: Number(map.version),
|
||||
mappings: typeof map.mappings === 'string' ? map.mappings : '',
|
||||
}
|
||||
}
|
||||
function genCSSModulesCode(
|
||||
// @ts-ignore
|
||||
id, index, request, requestWithoutModule, moduleName) {
|
||||
const styleVar = `style${index}`
|
||||
let code =
|
||||
// first import the CSS for extraction
|
||||
`\nimport ${_(requestWithoutModule)}` +
|
||||
// then import the json file to expose to component...
|
||||
`\nimport ${styleVar} from ${_(request + '.js')}`
|
||||
// inject variable
|
||||
const name = typeof moduleName === 'string' ? moduleName : '$style'
|
||||
code += `\ncssModules["${name}"] = ${styleVar}`
|
||||
return code
|
||||
}
|
||||
// overwrite for cjs require('rollup-plugin-vue')() usage
|
||||
module.exports = PluginVue
|
@ -8,7 +8,7 @@ import typescript from 'rollup-plugin-typescript2'
|
||||
import pkg from '../package.json'
|
||||
const deps = Object.keys(pkg.dependencies)
|
||||
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
||||
const vue = require('./plugin.js')
|
||||
const vue = require('rollup-plugin-vue')
|
||||
|
||||
export default [
|
||||
{
|
||||
|
@ -70,7 +70,7 @@
|
||||
"rollup-plugin-css-only": "^2.1.0",
|
||||
"rollup-plugin-terser": "^7.0.2",
|
||||
"rollup-plugin-typescript2": "^0.27.3",
|
||||
"rollup-plugin-vue": "^6.0.0-beta.10",
|
||||
"rollup-plugin-vue": "^6.0.0-beta.11",
|
||||
"sass": "^1.26.10",
|
||||
"sass-loader": "^10.0.1",
|
||||
"style-loader": "^1.2.1",
|
||||
|
@ -46,7 +46,6 @@ import {
|
||||
computed,
|
||||
watch,
|
||||
onMounted,
|
||||
nextTick,
|
||||
ComponentPublicInstance,
|
||||
} from 'vue'
|
||||
import { on, addClass, removeClass } from '@element-plus/utils/dom'
|
||||
|
@ -10217,9 +10217,10 @@ rollup-plugin-typescript2@^0.27.3:
|
||||
resolve "1.17.0"
|
||||
tslib "2.0.1"
|
||||
|
||||
rollup-plugin-vue@^6.0.0-beta.10:
|
||||
version "6.0.0-beta.10"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-vue/-/rollup-plugin-vue-6.0.0-beta.10.tgz#66d9b9a8dd2d085267d1cc398ea0113360879ac1"
|
||||
rollup-plugin-vue@^6.0.0-beta.11:
|
||||
version "6.0.0-beta.11"
|
||||
resolved "https://registry.yarnpkg.com/rollup-plugin-vue/-/rollup-plugin-vue-6.0.0-beta.11.tgz#fdbc6b7484a361ef8c5e8009cef4a6bd45435013"
|
||||
integrity sha512-osqLkFc7N76TOI0CeW0BOujlMFsMIoytyTRVUivaeYSMponNfk1iSuqyoeciUB3EjFqyL/dTTFPi+7rhaAm73w==
|
||||
dependencies:
|
||||
debug "^4.1.1"
|
||||
hash-sum "^2.0.0"
|
||||
|
Loading…
Reference in New Issue
Block a user