在aurelia项目中,我有几个组件可以导入其他样式表,例如来自语义ui。离开组件页面后,样式表仍处于活动状态,不会被删除。是否有可能卸载'样式表?
答案 0 :(得分:1)
我提交了一个PR以启用此选项,您可以在此处跟踪:https://github.com/aurelia/templating-resources/pull/344
一句警告,这是未经测试的,而且是aurelia-internals-hacky。
所能做的是覆盖默认的CSSViewEngineHooks
和CSSResource
类,以跟踪它注入的样式元素,然后添加beforeUnbind
个钩子再次删除样式..在unbind之前(在分离之后)
不幸的是,CSSResource
类不是从aurelia-templating-resources
导出的,所以我们需要更深层地覆盖一层并覆盖返回CSSResource
实例的现有样式加载器插件。
以下是:
首先我们从aurelia-templating-resources/src/css-resource.js
获取代码,将其放入我们自己的src/css-resource.js/ts
并对其进行一些调整(不要过多考虑它的大小,它是' s只是一个带有一些小调整的复制粘贴,注释注释):
import {ViewResources, resource, ViewCompileInstruction} from 'aurelia-templating';
import {Loader} from 'aurelia-loader';
import {Container} from 'aurelia-dependency-injection';
import {relativeToFile} from 'aurelia-path';
import {DOM, FEATURE} from 'aurelia-pal';
let cssUrlMatcher = /url\((?!['"]data)([^)]+)\)/gi;
function fixupCSSUrls(address, css) {
if (typeof css !== 'string') {
throw new Error(`Failed loading required CSS file: ${address}`);
}
return css.replace(cssUrlMatcher, (match, p1) => {
let quote = p1.charAt(0);
if (quote === '\'' || quote === '"') {
p1 = p1.substr(1, p1.length - 2);
}
return 'url(\'' + relativeToFile(p1, address) + '\')';
});
}
class CSSResource {
constructor(address: string) {
this.address = address;
this._scoped = null;
this._global = false;
this._alreadyGloballyInjected = false;
}
initialize(container: Container, target: Function): void {
this._scoped = new target(this);
}
register(registry: ViewResources, name?: string): void {
if (name === 'scoped') {
registry.registerViewEngineHooks(this._scoped);
} else {
this._global = true;
}
}
load(container: Container): Promise<CSSResource> {
return container.get(Loader)
.loadText(this.address)
.catch(err => null)
.then(text => {
text = fixupCSSUrls(this.address, text);
this._scoped.css = text;
if (this._global) {
this._alreadyGloballyInjected = true;
// DOM.injectStyles(text); <- replace this
// this is one of the two possible moments where the style is injected
// _scoped is the CSSViewEngineHooks instance, and we handle the removal there
this._scoped.styleNode = DOM.injectStyles(text);
}
});
}
}
class CSSViewEngineHooks {
constructor(owner: CSSResource) {
this.owner = owner;
this.css = null;
}
beforeCompile(content: DocumentFragment, resources: ViewResources, instruction: ViewCompileInstruction): void {
if (instruction.targetShadowDOM) {
DOM.injectStyles(this.css, content, true);
} else if (FEATURE.scopedCSS) {
let styleNode = DOM.injectStyles(this.css, content, true);
styleNode.setAttribute('scoped', 'scoped');
} else if (this._global && !this.owner._alreadyGloballyInjected) {
// DOM.injectStyles(this.css); <- replace this
// save a reference to the node so we can easily remove it later
this.styleNode = DOM.injectStyles(this.css);
this.owner._alreadyGloballyInjected = true;
}
}
// this is the hook we add, here we remove the node again
beforeUnbind(): void {
if (this._global && this.owner._alreadyGloballyInjected) {
DOM.removeNode(this.styleNode);
this.owner._alreadyGloballyInjected = false;
}
}
}
export function _createCSSResource(address: string): Function {
@resource(new CSSResource(address))
class ViewCSS extends CSSViewEngineHooks {}
return ViewCSS;
}
然后,在main.ts/js
aurelia-templating-resources.js
我们做同样的事情aurelia.use.standardConfiguration()
,但我们自己的版本。
所以我们在<{>}之后执行 来覆盖现有的
let viewEngine = config.container.get(ViewEngine);
let styleResourcePlugin = {
fetch(address) {
return { [address]: _createCSSResource(address) };
}
};
['.css', '.less', '.sass', '.scss', '.styl'].forEach(ext => viewEngine.addResourcePlugin(ext, styleResourcePlugin));
这应该可以解决问题.. :)
答案 1 :(得分:0)
我找到了解决此问题的插件: https://kuba-halle.de/tickets
但是对于最新的Webpack webpack.config.js
,应该与插件自述文件有所不同。
您应该通过以下方式加载.css
文件:
use: [
{ loader: 'style-loader', options: { injectType: 'lazyStyleTag' } },
'css-loader'
]
代替此:
use: ['style-loader/useable', 'css-loader']