Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions src/__tests__/test-process-tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import processTpl, {
genLinkReplaceSymbol,
genModuleScriptReplaceSymbol,
genScriptReplaceSymbol,
processCssContent,
} from '../process-tpl';

test('test process-tpl', () => {
Expand Down Expand Up @@ -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();
});
5 changes: 3 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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), `<style>/* ${styleSrc} */${styleSheets[i]}</style>`);
const styleText = processCssContent(styleSrc, styleSheets[i]);
html = html.replace(genLinkReplaceSymbol(styleSrc), `<style>/* ${styleSrc} */${styleText}</style>`);
return html;
}, embedHTML);
return embedHTML;
Expand Down
33 changes: 32 additions & 1 deletion src/process-tpl.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

喔嚯, 兄弟,你这不考虑 https 吗?

}
return new URL(path, newBaseURI).toString();
}

function isValidJavaScriptType(type) {
Expand All @@ -43,7 +49,32 @@ export const genScriptReplaceSymbol = (scriptSrc, async = false) => `<!-- ${asyn
export const inlineScriptReplaceSymbol = `<!-- inline scripts replaced by import-html-entry -->`;
export const genIgnoreAssetReplaceSymbol = url => `<!-- ignore asset ${url || 'file'} replaced by import-html-entry -->`;
export const genModuleScriptReplaceSymbol = (scriptSrc, moduleSupport) => `<!-- ${moduleSupport ? 'nomodule' : 'module'} script ${scriptSrc} ignored by import-html-entry -->`;
/**
* 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
Expand Down