diff --git a/src/__tests__/test-process-tpl.js b/src/__tests__/test-process-tpl.js
index 2e09da7..8fa26f8 100644
--- a/src/__tests__/test-process-tpl.js
+++ b/src/__tests__/test-process-tpl.js
@@ -4,6 +4,7 @@ import processTpl, {
genLinkReplaceSymbol,
genModuleScriptReplaceSymbol,
genScriptReplaceSymbol,
+ processCssContent,
} from '../process-tpl';
test('test process-tpl', () => {
@@ -318,3 +319,26 @@ test('should work with huge html content', () => {
const during = Date.now() - start;
expect(during < 1000).toBeTruthy();
});
+
+test('test process url in external css resources', () => {
+ const transformedStyleText = processCssContent('//cdntest.com/css/ui.css', `
+ @import 'component1.css'
+ @import url('component2.less')
+ .test-notice {
+ background: #ffffff url(../images/bg1.jpg) no-repeat center left;
+ background-image: url( '../images/bg2.jpg' );
+ background-image: url("../images/bg3.jpg");
+ background-image: url("//test.com/images/bg4.jpg");
+ background-image: url("http://test.com/images/bg5.jpg");
+ };
+ /*# sourceMappingURL=test-notice.css.map */
+ `);
+ expect(transformedStyleText.indexOf('//cdntest.com/css/component1.css') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//cdntest.com/css/component2.less') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//cdntest.com/images/bg1.jpg') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//cdntest.com/images/bg2.jpg') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//cdntest.com/images/bg3.jpg') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//test.com/images/bg4.jpg') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('http://test.com/images/bg5.jpg') !== -1).toBeTruthy();
+ expect(transformedStyleText.indexOf('//cdntest.com/css/test-notice.css.map') !== -1).toBeTruthy();
+});
\ No newline at end of file
diff --git a/src/index.js b/src/index.js
index 28fd294..a096a68 100644
--- a/src/index.js
+++ b/src/index.js
@@ -4,7 +4,7 @@
* @since 2018-08-15 11:37
*/
-import processTpl, { genLinkReplaceSymbol, genScriptReplaceSymbol } from './process-tpl';
+import processTpl, { genLinkReplaceSymbol, genScriptReplaceSymbol, processCssContent } from './process-tpl';
import {
defaultGetPublicPath,
getGlobalProp,
@@ -40,7 +40,8 @@ function getEmbedHTML(template, styles, opts = {}) {
return getExternalStyleSheets(styles, fetch)
.then(styleSheets => {
embedHTML = styles.reduce((html, styleSrc, i) => {
- html = html.replace(genLinkReplaceSymbol(styleSrc), ``);
+ const styleText = processCssContent(styleSrc, styleSheets[i]);
+ html = html.replace(genLinkReplaceSymbol(styleSrc), ``);
return html;
}, embedHTML);
return embedHTML;
diff --git a/src/process-tpl.js b/src/process-tpl.js
index bdd1b2e..19c55d3 100644
--- a/src/process-tpl.js
+++ b/src/process-tpl.js
@@ -30,7 +30,13 @@ function hasProtocol(url) {
}
function getEntirePath(path, baseURI) {
- return new URL(path, baseURI).toString();
+ // 防止new URL(path, '//xxx...')这种形式报错: Invalid base URL
+ // by daniel@2021-06-22
+ let newBaseURI = baseURI;
+ if (baseURI.indexOf('//') === 0) {
+ newBaseURI = 'http:' + baseURI;
+ }
+ return new URL(path, newBaseURI).toString();
}
function isValidJavaScriptType(type) {
@@ -43,7 +49,32 @@ export const genScriptReplaceSymbol = (scriptSrc, async = false) => ``;
export const genIgnoreAssetReplaceSymbol = url => ``;
export const genModuleScriptReplaceSymbol = (scriptSrc, moduleSupport) => ``;
+/**
+ * process the css content, transform the relative url in external css to absolute path.
+ *
+ * @author Daniel
+ * @since 2021-06-22
+ * @param {string} styleSrc the external css link
+ * @param {string} styleText the fetched css content
+ * @returns
+ */
+ export const processCssContent = (styleSrc, styleText) => {
+ const replacement = function (match, prefix, path, suffix) {
+ if (hasProtocol(path)) {
+ return match;
+ }
+ const newHref = getEntirePath(path, styleSrc);
+ return prefix + newHref + suffix;
+ };
+
+ const transformedStyleText = styleText
+ .replace(/(@import\s*['"])([^'"]+)(['"])/g, replacement) // transform leading `@import 'xxx.css'`
+ .replace(/(url\(\s*['"]?)([^'"\s\(\)]+)(['"]?\s*\))/g, replacement) // transform `url(xxx.jpg)`
+ .replace(/(\/[*\/][@#] sourceMappingURL=)(\S+)(( \*\/)?[\r\n]*)$/mg, replacement); // transform trailing `sourceMappingURL=xxx.map`
+
+ return transformedStyleText;
+};
/**
* parse the script link from the template
* 1. collect stylesheets