在下游css中使用来自ClientBundle的混淆CSS名称

时间:2010-08-31 18:43:57

标签: css gwt

我有一个带有一些CSS的库,以及一个扩展CSS的依赖项目。我正试图将它们都移到ClientBundle。

目前,library.css是

.smallWindow { min-width: 10px; outline: none; }

depProject.css是

.sectionA .smallWindow { color: blue; }

我将library.css和depProject.css移动到各自项目中的ClientBundles(LibraryBundle和DepProjectBundle)中,但必须将smallWindow标记为外部。有没有办法将depProject.css中的smallWindow链接到library.css中的smallWindow并仍然对smallWindow进行模糊处理?

我希望不是标记@external .smallWindow我可以将它留在library.css中,并将@replaceWithObfuscated smallWindow DepProjectBundle.css.smallWindow之类的东西放在depProject.css的顶部

1 个答案:

答案 0 :(得分:4)

注释被称为@external有一个原因:)它适用于外部类,我们无法控制其名称 - 这适合您的情况。碰巧你的外部项目也是一个GWT,但这并不重要 - 除非你同时编译两个项目,我没有看到任何(简单和非hackish)方式(自动)链接从LibraryBundle到DepProjectBundle的模糊类名。

<tech (?) rant>
ClientBundle在编译时完成所有工作 - 它在那时知道关于CSS的所有内容,例如,可以为UiBinder模板中包含的所有类名创建非冲突类名(<ui:style>元素转换为编译时CssResource。因此,您可以在.warning'UiBinder模板中使用名为WidgetA的CSS类,在.warning中使用不同的WidgetB类作为UiBinder模板。在编译期间,他们将被分配不同的混淆名称(因为他们不同的类)。现在,让我们转到你的情况:你编译LibraryBundle然后你编译(独立)DepProjectBundle - 它是可能的(混淆前缀越短,你应该覆盖默认的长GWT前缀BTW),在这两个项目中你将获得相同的命名CSS类(当然,它们很可能具有不同的目的)。因此,如果您盲目地将LibraryBundle中的一个类包含到DepProjectBundle中,您可能(在某些时候)引入名称冲突。
</tech (?) rant>

如果你真的想避免@external(这是一个好主意,我会承认:)),我建议如下:将你的LibraryBundle作为svn:externals包含在你的项目中(你使用SCM,对吗?)或符号链接或SCM或文件系统中可用的任何其他方法 - 基本上,你将能够无缝地在许多项目中共享相同的LibraryBundle代码(我认为这是目标),同时得到GWT编译器的编译时支持。


回应史蒂夫的评论更新:

我似乎从你最初的问题误解了你的项目结构 - 我的印象是你想要链接到LibraryBundle的编译输出......但是因为你正在使用源代码(通过Maven,很好: )),那么我的svn:externals想法是不需要的(顺便说一句,你可以在svn:externals属性中放置任何存储库路径,包括你的主干分支。)
无论如何,我的印象是人们可以很容易地将两个CssResource合并为一个但是唉...... 这是我到目前为止所尝试过的,都失败了,但也许这个列表中的某些内容会引发在某人身上有一些好主意;)(在这里提出一个很长的清单......)抓一点,在总结我失败的过程中,我想出了答案:)

答案是:

@Import注释(与@ImportedWithPrefix结合使用可获得更有意义的前缀)。您的ProjectBundle将如下所示:

public interface DepProjectBundle extends ClientBundle {
    public static final DepProjectBundle INSTANCE = GWT.create(DepProjectBundle.class);
    // Need this to reference the class names
    // But maybe we can use the one in LibraryBundle?
    // Have fun testing that :) For simplicty, I'll leave it here
    Library library();

    // The good stuff
    @Import({Library.class})
    Main main();
}

Library是来自CssResource的{​​{1}}(或者可能是整个LibraryBundle?还没试过)重要的是LibraryBundle注释(普通的CSS @Import不适用于@import url(some.css) - 我试过了;))
现在,您可以使用此ClientBundle

DepProjectBundle

请注意,我们使用DepProjectBundle.INSTANCE.library().ensureInjected(); DepProjectBundle.INSTANCE.main().ensureInjected(); Label label = new Label("Test"); label.addStyleName(DepProjectBundle.INSTANCE.library().smallWindow()); VerticalPanel vPanel = new VerticalPanel(); vPanel.addStyleName(DepProjectBundle.INSTANCE.main().sectionA()); vPanel.add(label); RootPanel.get().add(vPanel); CssResource来引用library.css“namespace”中的名称。
然而,在main.css 中需要进行一项重要更改 - 为了避免名称冲突,编译器使用前缀导入类名 - 它使用类的名称或通过{{提供的名称3}}注释。所以,你的main.css必须改成这样的东西(我们假设你使用DepProjectBundle.library()作为前缀):

library

不幸的是,没有办法解决这个问题(我发现:)。但是从长远来看它可能是有益的 - 如果你忘记了你在library.css中使用的名字以及main.css中的哪些名字(这可能会导致一些奇怪的CSS冲突) - 这样你就可以清楚地定义了(在main.css中) )这个类名属于library.css(它最终会被混淆,因此不会浪费额外的字节)。

Phew,希望这个解决方案对你(以及其他人有帮助!))我也会留下我最初的想法,因为其他人可能没有(从一开始:)使用外部ClientBundle的来源,.sectionA .library-smallWindow { color: blue; } 想法可能对不使用maven等工具的人有用。