mirror of
https://github.com/vuejs/vue-cli.git
synced 2026-01-17 04:40:03 -06:00
115 lines
4.0 KiB
JavaScript
115 lines
4.0 KiB
JavaScript
/*
|
|
The MIT License (MIT)
|
|
Copyright (c) 2016 Jan Nicklas
|
|
https://github.com/DustinJackson/html-webpack-inline-source-plugin/blob/master/LICENSE
|
|
|
|
Modified by Yuxi Evan You
|
|
*/
|
|
|
|
const path = require('path')
|
|
const slash = require('slash')
|
|
const sourceMapUrl = require('source-map-url')
|
|
const escapeRegex = require('escape-string-regexp')
|
|
|
|
module.exports = class InlineSourcePlugin {
|
|
constructor (options = {}) {
|
|
this.options = options
|
|
}
|
|
|
|
apply (compiler) {
|
|
// Hook into the html-webpack-plugin processing
|
|
compiler.plugin('compilation', compilation => {
|
|
compilation.plugin('html-webpack-plugin-before-html-generation', (htmlPluginData, callback) => {
|
|
callback(null, htmlPluginData)
|
|
})
|
|
compilation.plugin('html-webpack-plugin-alter-asset-tags', (htmlPluginData, callback) => {
|
|
if (!this.options.include) {
|
|
return callback(null, htmlPluginData)
|
|
}
|
|
const regex = this.options.include
|
|
const result = this.processTags(compilation, regex, htmlPluginData)
|
|
callback(null, result)
|
|
})
|
|
})
|
|
}
|
|
|
|
processTags (compilation, regex, pluginData) {
|
|
const processTag = tag => this.processTag(compilation, regex, tag)
|
|
return Object.assign({}, pluginData, {
|
|
head: pluginData.head.map(processTag),
|
|
body: pluginData.body.map(processTag)
|
|
})
|
|
}
|
|
|
|
processTag (compilation, regex, tag) {
|
|
let assetUrl
|
|
|
|
// inline js
|
|
if (tag.tagName === 'script' && regex.test(tag.attributes.src)) {
|
|
assetUrl = tag.attributes.src
|
|
tag = {
|
|
tagName: 'script',
|
|
closeTag: true,
|
|
attributes: {
|
|
type: 'text/javascript'
|
|
}
|
|
}
|
|
|
|
// inline css
|
|
} else if (tag.tagName === 'link' && regex.test(tag.attributes.href)) {
|
|
assetUrl = tag.attributes.href
|
|
tag = {
|
|
tagName: 'style',
|
|
closeTag: true,
|
|
attributes: {
|
|
type: 'text/css'
|
|
}
|
|
}
|
|
}
|
|
|
|
if (assetUrl) {
|
|
// Strip public URL prefix from asset URL to get Webpack asset name
|
|
const publicUrlPrefix = compilation.outputOptions.publicPath || ''
|
|
const assetName = path.posix.relative(publicUrlPrefix, assetUrl)
|
|
const asset = compilation.assets[assetName]
|
|
// do not emit inlined assets
|
|
delete compilation.assets[assetName]
|
|
const updatedSource = this.resolveSourceMaps(compilation, assetName, asset)
|
|
tag.innerHTML = (tag.tagName === 'script') ? updatedSource.replace(/(<)(\/script>)/g, '\\x3C$2') : updatedSource
|
|
}
|
|
|
|
return tag
|
|
}
|
|
|
|
resolveSourceMaps (compilation, assetName, asset) {
|
|
let source = asset.source()
|
|
const out = compilation.outputOptions
|
|
// Get asset file absolute path
|
|
const assetPath = path.join(out.path, assetName)
|
|
// Extract original sourcemap URL from source string
|
|
if (typeof source !== 'string') {
|
|
source = source.toString()
|
|
}
|
|
const mapUrlOriginal = sourceMapUrl.getFrom(source)
|
|
// Return unmodified source if map is unspecified, URL-encoded, or already relative to site root
|
|
if (!mapUrlOriginal || mapUrlOriginal.indexOf('data:') === 0 || mapUrlOriginal.indexOf('/') === 0) {
|
|
return source
|
|
}
|
|
// Figure out sourcemap file path *relative to the asset file path*
|
|
const assetDir = path.dirname(assetPath)
|
|
const mapPath = path.join(assetDir, mapUrlOriginal)
|
|
const mapPathRelative = path.relative(out.path, mapPath)
|
|
// Starting with Node 6, `path` module throws on `undefined`
|
|
const publicPath = out.publicPath || ''
|
|
// Prepend Webpack public URL path to source map relative path
|
|
// Calling `slash` converts Windows backslashes to forward slashes
|
|
const mapUrlCorrected = slash(path.join(publicPath, mapPathRelative))
|
|
// Regex: exact original sourcemap URL, possibly '*/' (for CSS), then EOF, ignoring whitespace
|
|
const regex = new RegExp(escapeRegex(mapUrlOriginal) + '(\\s*(?:\\*/)?\\s*$)')
|
|
// Replace sourcemap URL and (if necessary) preserve closing '*/' and whitespace
|
|
return source.replace(regex, (match, group) => {
|
|
return mapUrlCorrected + group
|
|
})
|
|
}
|
|
}
|