You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
parttimejob/node_modules/@vue/cli-service/lib/webpack/ModernModePlugin.js

87 lines
3.0 KiB

1 month ago
const fs = require('fs-extra')
const path = require('path')
const HtmlWebpackPlugin = require('html-webpack-plugin')
class ModernModePlugin {
constructor ({ targetDir, isModuleBuild }) {
this.targetDir = targetDir
this.isModuleBuild = isModuleBuild
}
apply (compiler) {
if (!this.isModuleBuild) {
this.applyLegacy(compiler)
} else {
this.applyModule(compiler)
}
}
applyLegacy (compiler) {
const ID = `vue-cli-legacy-bundle`
compiler.hooks.compilation.tap(ID, compilation => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(ID, async (data, cb) => {
// get stats, write to disk
await fs.ensureDir(this.targetDir)
const htmlName = path.basename(data.plugin.options.filename)
// Watch out for output files in sub directories
const htmlPath = path.dirname(data.plugin.options.filename)
const tempFilename = path.join(this.targetDir, htmlPath, `legacy-assets-${htmlName}.json`)
await fs.mkdirp(path.dirname(tempFilename))
let tags = data.bodyTags
if (data.plugin.options.scriptLoading === 'defer') {
tags = data.headTags
}
await fs.writeFile(tempFilename, JSON.stringify(tags))
cb()
})
})
}
applyModule (compiler) {
const ID = `vue-cli-modern-bundle`
compiler.hooks.compilation.tap(ID, compilation => {
HtmlWebpackPlugin.getHooks(compilation).alterAssetTagGroups.tapAsync(ID, async (data, cb) => {
let tags = data.bodyTags
if (data.plugin.options.scriptLoading === 'defer') {
tags = data.headTags
}
// use <script type="module"> for modern assets
tags.forEach(tag => {
if (tag.tagName === 'script' && tag.attributes) {
tag.attributes.type = 'module'
}
})
// use <link rel="modulepreload"> instead of <link rel="preload">
// for modern assets
data.headTags.forEach(tag => {
if (tag.tagName === 'link' &&
tag.attributes.rel === 'preload' &&
tag.attributes.as === 'script') {
tag.attributes.rel = 'modulepreload'
}
})
// inject links for legacy assets as <script nomodule>
const htmlName = path.basename(data.plugin.options.filename)
// Watch out for output files in sub directories
const htmlPath = path.dirname(data.plugin.options.filename)
const tempFilename = path.join(this.targetDir, htmlPath, `legacy-assets-${htmlName}.json`)
const legacyAssets = JSON.parse(await fs.readFile(tempFilename, 'utf-8'))
.filter(a => a.tagName === 'script' && a.attributes)
legacyAssets.forEach(a => { a.attributes.nomodule = '' })
tags.push(...legacyAssets)
await fs.remove(tempFilename)
cb()
})
HtmlWebpackPlugin.getHooks(compilation).beforeEmit.tap(ID, data => {
data.html = data.html.replace(/\snomodule="">/g, ' nomodule>')
})
})
}
}
module.exports = ModernModePlugin