首页 文章

使用webpack生成静态CSS文件

提问于
浏览
4

我目前正在开发一个使用不同前端主题的应用程序 . 这些主题只是CSS文件,可由用户选择 .

从技术上讲,这些主题是.scss文件,它们由webpack编译并通过angular中的标准link-tag加载:

<link rel="stylesheet", ng-href="themes/{{theme}}.css">

我剥离的webpack配置如下所示:

theme1CssExtractor = new ExtractTextPlugin('themes/theme-1.css'),     
theme2CssExtractor = new ExtractTextPlugin('themes/theme-2.css'),     

module.exports = new WebpackConfig().merge({

entry: {
    app: [
        './app/main.ts',
        './assets/sass/themes/theme-1.scss',
        './assets/sass/themes/theme-2.scss'
    ],
},

output: {
    path: "build/",
    filename: "[name].bundle.js",
    publicPath: "/build/"
},

plugins: [
    theme1CssExtractor,
    theme2CssExtractor,
],

module: {
    loaders: [
        {
            test: /\.ts$/,
            loaders: ['awesome-typescript-loader']
        },
        [
            {
                test: /theme-1\.scss$/,
                include: path.resolve(__dirname, "assets/sass/themes"),
                loader: theme1CssExtractor.extract(
                    "style",
                    "css!sass?includePaths[]=" + path.resolve(__dirname, './node_modules/compass-mixins/lib')
                )
            },
            {
                test: /theme-2\.scss$/,
                include: path.resolve(__dirname, "assets/sass/themes"),
                loader: theme2CssExtractor.extract(
                    "style",
                    "css!sass?includePaths[]=" + path.resolve(__dirname, './node_modules/compass-mixins/lib')
                )
            }
        ]
    ]
}

这完全正常,直到我想使用启用了热模块替换(HMR)功能的webpack-dev-server,因为extractTextPlugin不支持HMR . 当我简单地禁用extractTextPlugin(options.disable)或删除它们时,所有主题都被编译到主模块中,这个 - 来源 - 打破主题,因为所有主题都应用在一起 .

如何在不使用extractTextPlugin的情况下直接使用webpack生成这些CSS文件?我尝试了不同的enntries / chunk,文件加载器的各种尝试......但没有什么真正有效 .

它应该很简单:从SCSS-Files生成静态CSS文件,而不使用ExtractTextPlugin将它们转换为JS文件 .

如果有人能指出我正确的方向,那就太好了 .

1 回答

  • 2

    一种方法可能是以尊重不同模式的方式组织Webpack配置:

    • 开发:不要使用ExtractTextPlugin(稍后会看到包含所有内容的文件的问题)

    • production:像现在一样使用ExtractTextPlugin

    您可以在este中查看它是如何完成的 .

    关于没有ExtractTextPlugin(一个包含所有主题的文件)的问题:它发生是因为你的配置包含 theme-1.scsstheme-2.scss 作为'app'块中的入口点,所以Webpack将它们放在一起(一个块) . 您可以尝试另一种方式:从入口点列表中排除它们,并在源代码中添加如下内容:

    require('../assets/sass/themes/' + theme + '.scss');
    

    在这种情况下,在开发模式下,您将只获得一个模块(主题),具体取决于变量“theme”的值 . 在 生产环境 模式下,Webpack将遍历'assets / sass / themes /'中的所有文件('require'包含表达式时的特定Webpack行为),包括它们作为模块,然后ExtractTextPlugin将处理它们的提取(所以你没有在这做任何事情) .

    有一些棘手的部分关于如何在 生产环境 中加载特定主题(因为"require"你在代码中没有做任何事情,ExtractTextPlugin会将相应的模块留空)所以你必须把一些代码添加 <link><head> 你的HTML . 同时,不应在开发模式下调用此代码 . 一个可以帮助实现它的肮脏黑客:

    if (!__DEV__) {
      // do adding <link> to the <head>
    }
    

    (另请参阅este示例,如何使用DefinePlugin定义 __DEV__ 变量) .

    我真的很好奇如何以更好的方式解决它......

相关问题