如何使用 WebPack 将所有的 CSS 文件合并成一个文件?

11
我对WebPack还比较新,我想把一个CSS文件目录(.app/styles/[css files...])输出到一个CSS文件(dist/styles.css)中。
目前,所有JavaScript文件都编译成一个单独的“index_bundle.js”文件,这很完美,但我想为我的CSS文件实现相同的效果。
经过大量的搜索后,我发现WebPack的ExtractTextPlugin应该能够帮助解决这个问题,但这只适用于添加到“entry”属性的一个CSS文件(例如:entry: {style: "./app/styles/style.css"}),然后将其作为链接标记添加到HTML的头部,这很好,但我希望所有的CSS文件都放在一个styles.css文件中,然后将其作为链接添加到HTML的头部。
我的当前WebPack配置如下:
var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "styles.css", 
    {
        allChunks: false
    }
);

module.exports = {
    entry: {
        index: "./app/index.js"//,
        //styles: "./app/styles/style1.css" // I don't want one file, I want to use a directory eg: "./app/styles/"
    },
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            }
        ]
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}

请有人能帮我指明正确的方向吗?即使是另一个插件或不同的方法也可以。非常感谢任何帮助!

编辑: 我的新WebPack配置如下:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "index_bundle.css"
);

module.exports = {
    entry: [
        './app/index.js',
        './app/index.css'
    ],
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        preloaders: [
            {
                test: /\.css/,
                exclude: /styles/, 
                loader: 'import-glob-loader'
            }
        ],
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /styles\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            },
            { 
                test: /\.json$/, 
                loader: 'json' 
            }
        ]
    },
    devServer: {
        historyApiFallback: true
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}

1
Webpack的工作方式是遍历主入口文件的依赖树(导入)。因此,通常情况下,要将目录中的所有CSS捆绑在一起,您需要创建一个名为styles.css的索引,并@import所有其他CSS文件(按照您希望它们出现在捆绑包中的顺序)。 - Davin Tryon
那是否意味着每次添加新的CSS文件时,我都必须记得放置所有的@imports? - Fred
1
不,你需要使用全局导入:@import './mydir/**/*.css' - Davin Tryon
我正在使用 "import-glob-loader",但是现在在运行webpack dev服务器时出现错误:"意外字符 '@'"。当我删除css条目时,它可以正常工作,因此似乎即使使用glob预加载程序也会在语法上失败... - Fred
2个回答

9

好的,看起来这是一个驼峰命名问题。

Davin Tryon的帮助下,我成功解决了我的问题 - 谢谢!

如果你查看:https://www.npmjs.com/package/import-glob-loader 他们有以下内容:

preloaders: [{
    test: /\.scss/,
    loader: 'import-glob-loader'
}]

应该是:

preLoaders: [{
    test: /\.scss/,
    loader: 'import-glob-loader'
}]

最终,我的整个webpack.config.json看起来像这样:

var HtmlWebpackPlugin = require('html-webpack-plugin');
var HtmlWebpackPluginConfig = new HtmlWebpackPlugin({
    template: __dirname + '/app/index.html',
    filename: 'index.html',
    inject: 'body'
});

var ExtractTextPlugin = require('extract-text-webpack-plugin');
var ExtractTextPluginConfig = new ExtractTextPlugin(
    "index_bundle.css"
);

module.exports = {
    entry: [
        './app/index.js',
        './app/index.css'
    ],
    output: {
        path: __dirname + '/dist',
        filename: 'index_bundle.js'
    },
    module: {
        preLoaders: [
            {
                test: /\.css$/,
                exclude: /styles/, 
                loader: 'import-glob-loader'
            }
        ],
        loaders: [
            {
                test: /\.js$/, 
                exclude: /node_modules/, 
                loader: 'babel-loader'
            },
            { 
                test: /\.css$/, 
                loader: ExtractTextPlugin.extract("style-loader", "css-loader")
            },
            { 
                test: /\.json$/, 
                loader: 'json' 
            }
        ]
    },
    devServer: {
        historyApiFallback: true
    },
    plugins: [
        HtmlWebpackPluginConfig,
        ExtractTextPluginConfig
    ]
}

我的index.css文件如下所示:

@import './styles/**/*';

这对我有作用,我得到了一个单独的CSS输出文件“index_bundle.css”。 样式和脚本也自动注入到HTML模板中。

注入前的index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Admin - Login</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css"/>
    </head>
    <body>
        <div id="app"></div>
    </body>
</html>

注入后在/dist文件夹中的index.html:

<!DOCTYPE html>
<html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Admin - Login</title>
        <link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/latest/css/bootstrap.min.css"/>
    <link href="index_bundle.css" rel="stylesheet"></head>
    <body>
        <div id="app"></div>
    <script type="text/javascript" src="index_bundle.js"></script></body>
</html>

哇,这是关于在Webpack中提取CSS的第一个可行的教程!谢谢! - b1r3k
很高兴能帮到你,兄弟! - Fred
6
注意:module.preLoaders已在Webpack 2中移除。 - myconode

0

我曾经遇到过类似的问题,因为在我的webpack.config.js文件中有一个文件名的拼写错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接