0

我正在做一个小项目,我使用 webpack 来生成我的 js 和 css 代码的捆绑包,一切都很好,但是我试图做一个 web 组件来导入我在这里<link rel="stylesheet" href="yourcss1.css">读到的 css 样式,我可以在里面使用一个通用的用于导入样式的模板,但问题是当 webpack 构建捆绑包时可以将 css 文件移动到 dist 文件夹,我如何配置 webpack 以读取嵌套在模板中的 css 文件并移动到 dist 文件夹。

这是我的配置 webpack.config.js :

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

const webpackConfig = {
    entry: {
        home: ['@babel/polyfill', './src/js/home/home.js', 
       './src/sass/home/home.scss'],
        signup: ['@babel/polyfill', './src/js/signup/signup.js', './src/sass/signup/signup.scss'],
        me: ['@babel/polyfill', './src/js/me/me.js', './src/sass/me/me.scss']
    },
    devtool: 'source-map',
    output: {
        path: __dirname + '/dist',
        filename: 'js/[name].bundle.js?v=[hash]',
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-react-jsx']
                    }
                }
            },
            {
                test: /\.html$/,
                use: ['html-loader']
            }, 
            { test: /\.hbs$/,
                loader: "handlebars-loader"
            },
            {
                test: /\.scss$/,
                use: [
                    'to-string-loader',
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                    loader: 'file-loader',
                    options: {
                        context: '',
                        name: '[hash]-[name].[ext]',
                        outputPath: './img',
                        publicPath: '/img'
                    }
                }]
            },
            {
                test: /\.css$/i,
                use: [{
                    loader: 'file-loader',
                    options: {
                        context: '',
                        name: '[hash]-[name].[ext]',
                        outputPath: './img',
                        publicPath: '/img'
                    }
                }]
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].css?v=[hash]",
            chunkFilename: "[id].css"
        }),
        new CleanWebpackPlugin('./dist/')
    ],
    resolve: {
        modules: [
            path.resolve('./'),
            path.resolve('./node_modules'),
        ]
    },
    watch: process.env.NODE_ENV !== 'production',
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendor",
                    chunks: "initial"
                }
            }
        }
    },
    devServer: {
        // Display only errors to reduce the amount of output.
        stats: "errors-only",
        compress: true,
        contentBase: path.join(__dirname, 'dist'),
        host: process.env.HOST, // Defaults to `localhost`
        port: process.env.PORT, // Defaults to 8080
        open: 'http://localhost:8080/home.html', // Open the page in browser
    },
};
Object.keys(webpackConfig.entry).forEach((file) => {
    webpackConfig.plugins.push(
        new HtmlWebpackPlugin({
            filename: `${file}.html`,
            template: `src/template/${file}.html`,
            chunks: ['vendor', file.replace(/-(\w)/g, (match, c) => c.toUpperCase())]
        })
    );
});
module.exports = webpackConfig;

魔术表.hbs

<link type="text/css" rel="stylesheet" href="MagicTable.scss">
<div id="message-table" class="table">
    <div class="table-header">
        <div class="row">
            <div class="column col-email"><a href="#">Email</a></div>
            <div class="column col-message"><a href="#">Message</a></div>
            <!--<div class="column col-actions"><a href="#">Actions</a></div>-->
            <div class="column col-status"><a href="#">Estatus</a></div>
        </div>
    </div>
    <div class="table-content">
        <div class="row js-message-row">
            <div class="column col-email"><p>a@gmail.com</p></div>
            <div class="column col-message"><p>I want to play...</p></div>
            <!--<div class="column col-actions">&nbsp;</div>-->
            <div class="column col-status"><span class="status-circle circle-green"></span>
                <p class="green-text">Accepted</p></div>
        </div>
        <div class="row js-message-row">
            <div class="column col-email"><p>a@gmail.com</p></div>
            <div class="column col-message"><p>ASASFARGA</p></div>
            <!--<div class="column col-actions">&nbsp;</div>-->
            <div class="column col-status"><span class="status-circle circle-red"></span>
                <p class="red-text">Rejected</p></div>
        </div>
        <div class="row js-message-row">
            <div class="column col-email"><p>a@gmail.com</p></div>
            <div class="column col-message"><p>ASASFARGA</p></div>
            <div class="column col-status"><span class="status-circle circle-orange"></span>
                <p class="orange-text">Pending</p></div>
        </div>
    </div>
</div>

MagicTable.js

import template from './MagicTable.hbs';
class MagicTable extends HTMLElement {
    constructor() {
        super();
        let shadowRoot = this.attachShadow({mode: 'open'});
        shadowRoot.innerHTML = template({});
    }
}
//export default MagicTable
customElements.define('magic-table', MagicTable);
4

1 回答 1

0

对于<link rel="stylesheet" href="src/compontent/componentA.css">嵌套在组件模板中并转换 为的进程<link rel="stylesheet" href="css/componentA.css">,只需将这些加载程序添加到“handlerbars-loader”之后,该加载程序是为进程提取 css 文件。

{
            test: /\.hbs$/,
            use: [
                {
                    loader: "handlebars-loader",
                },
                {
                    loader: 'extract-loader'
                },
                {
                    loader: 'html-loader',
                    options: {
                        attrs: ["img:src", "link:href"],
                    }
                }]
        }

现在对于您需要添加的进程 css 链接:

{
            test: /\.css$/,
            loaders: [
                {
                    loader: "file-loader",
                    options: {
                        name: "css/[name].css?v=[hash]".toLocaleLowerCase(),
                    },
                },
                {
                    loader: "extract-loader",
                    options: {
                        publicPath: "../css",
                    }
                },
                {
                    loader: "css-loader",
                },
                {
                    loader: 'sass-loader'
                },
            ],
        },

这里完整的 webpack.config.js

const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const CleanWebpackPlugin = require('clean-webpack-plugin');
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const webpackConfig = {
    entry: {
        home: ['@babel/polyfill', './src/js/home/home.js', './src/sass/home/home.scss'],
        signup: ['@babel/polyfill', './src/js/signup/signup.js', './src/sass/signup/signup.scss'],
        me: ['@babel/polyfill', './src/js/me/me.js', './src/sass/me/me.scss']
    },
    devtool: 'source-map',
    output: {
        path: __dirname + '/dist',
        filename: 'js/[name].bundle.js?v=[hash]',
    },
    mode: 'development',
    module: {
        rules: [
            {
                test: /\.js$/,
                exclude: /node_modules/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['@babel/preset-env'],
                        plugins: ['@babel/plugin-proposal-class-properties', '@babel/plugin-transform-react-jsx']
                    }
                }
            },
            {
                test: /\.html$/,
                use: ['html-loader'],
            },
            {
                test: /\.hbs$/,
                use: [
                    {
                        loader: "handlebars-loader",
                    },
                    {
                        loader: 'extract-loader'
                    },
                    {
                        loader: 'html-loader',
                        options: {
                            attrs: ["img:src", "link:href"],
                        }
                    }]
            },
            {
                test: /\.scss$/,
                exclude: /components/,
                use: [
                    'to-string-loader',
                    MiniCssExtractPlugin.loader,
                    'css-loader',
                    'sass-loader',
                ]
            },
            {
                test: /\.(gif|png|jpe?g|svg)$/i,
                use: [{
                    loader: 'file-loader',
                    options: {
                        context: '',
                        name: '[hash]-[name].[ext]',
                        outputPath: './img',
                        publicPath: '/img'
                    }
                }]
            },
            {
                test: /\.css$/,
                loaders: [
                    {
                        loader: "file-loader",
                        options: {
                            name: "css/[name].css?v=[hash]".toLocaleLowerCase(),
                        },
                    },
                    {
                        loader: "extract-loader",
                        options: {
                            publicPath: "../css",
                        }
                    },
                    {
                        loader: "css-loader",
                    },
                    {
                        loader: 'sass-loader'
                    },
                ],
            },
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
            filename: "css/[name].css?v=[hash]",
            chunkFilename: "[id].css"
        }),
        new CleanWebpackPlugin('./dist/')
    ],
    resolve: {
        modules: [
            path.resolve('./'),
            path.resolve('./node_modules'),
        ]
    },
    watch: process.env.NODE_ENV !== 'production',
    optimization: {
        splitChunks: {
            cacheGroups: {
                commons: {
                    test: /[\\/]node_modules[\\/]/,
                    name: "vendor",
                    chunks: "initial"
                }
            }
        }
    },
    devServer: {
        // Display only errors to reduce the amount of output.
        stats: "errors-only",
        compress: true,
        contentBase: path.join(__dirname, 'dist'),
        host: process.env.HOST, // Defaults to `localhost`
        port: process.env.PORT, // Defaults to 8080
        open: 'http://localhost:8080/home.html', // Open the page in browser
    },
};
Object.keys(webpackConfig.entry).forEach((file) => {
    webpackConfig.plugins.push(
        new HtmlWebpackPlugin({
            filename: `${file}.html`,
            template: `src/template/${file}.html`,
            chunks: ['vendor', file.replace(/-(\w)/g, (match, c) => c.toUpperCase())]
        })
    );
});

module.exports = webpackConfig;
于 2019-02-22T04:39:18.970 回答