如何使用webpack 5将css和js分开?

5uzkadbs  于 2023-10-19  发布在  Webpack
关注(0)|答案(3)|浏览(193)

为了提高性能,我需要将CSS从Webpack配置中的JS分离到它自己的文件中。例如style.cssmain.js,或者我选择叫它们什么。目前我在我的主JS文件中导入css,如import 'style.css'
我怎么能改变这一点?
Webpack配置。

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
const isProduction = process.env.NODE_ENV === 'production';

const stylesHandler = 'style-loader';

const config  = {
  entry: './src/js/index.js',
  output: {
    path: path.resolve(__dirname, './dist/js'),
    filename: 'main.js',
    clean: true, // remove unused bundled files
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        loader: 'babel-loader',
      },
      {
        test: /\.css$/i,
        use: [stylesHandler, 'css-loader', 'postcss-loader'],
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|otf)$/i,
        type: 'asset',
      },
    ],
  },
};

module.exports = () => {
  if (isProduction) {
    config.mode = 'production';
  } else {
    config.mode = 'development';
  }
  return config;
};

Package.json(scripts)

"scripts": {
    "build": "webpack --mode=production --node-env=production",
    "build:dev": "webpack --mode=development",
    "build:prod": "webpack --mode=production --node-env=production",
    "watch": "webpack --watch"
  }
anauzrmj

anauzrmj1#

您可以添加MiniCssExtractPlugin,它似乎正是您想要的:
这个插件将CSS提取到单独的文件中。它为每个包含CSS的JS文件创建一个CSS文件。它支持按需加载CSS和SourceMaps。
它建立在一个新的webpack v5特性之上,需要webpack 5才能工作。
你的webpack.config.js最终应该有这样的东西:

module: {
  rules: [{
    test: /\.css$/i,
    use: [
      MiniCssExtractPlugin.loader,
      'css-loader',
      'postcss-loader',
    ],
  }],
},
brgchamk

brgchamk2#

您可以使用现代html-bundler-webpack-plugin
这个插件呈现包含脚本、样式、图像等源文件引用的HTML模板。
非常简单的用法示例:

<html>
<head>
  <!-- specify source style files -->
  <link href="./styles.scss" rel="stylesheet">
  <!-- specify source script files here and/or in body -->
  <script src="./main.js" defer="defer"></script>
</head>
<body>
  <h1>Hello World!</h1>
  <!-- specify source image files -->
  <img src="./picture.png">
</body>
</html>

您可以使用相对路径或Webpack别名在HTML中指定脚本、样式和图像源文件。

const HtmlBundlerPlugin = require('html-bundler-webpack-plugin');

module.exports = {
  plugins: [
    new HtmlBundlerPlugin({
      entry: {
          // define many templates here
          index: 'src/views/home.html', // => dist/index.html
        },
      },
      js: {
        // JS output filename, used if inline is false
        filename: 'js/[name].[contenthash:8].js',
        // inline: true, // inlines JS into HTML
      },
      css: {
        // CSS output filename, used if inline is false
        filename: 'css/[name].[contenthash:8].css',
        // inline: true, // inlines CSS into HTML
      },
    }),
  ],
  module: {
    rules: [
      {
        test: /\.(css|sass|scss)$/,
        use: ['css-loader', 'sass-loader'],
      },
      {
        test: /\.(ico|png|jp?g|webp|svg)$/,
        type: 'asset/resource',
        generator: {
          filename: 'img/[name].[hash:8][ext][query]',
        },
      },
    ],
  },
};

不需要额外的插件和加载器。
该插件检测模板中引用的所有源文件,并将处理后的资产提取到输出目录。编译的JS和CSS可以使用inline plugin选项内联到生成的HTML中。在生成的HTML和CSS中,插件用输出文件名替换源文件名。
生成的HTML包含已处理文件的输出文件名:

<html>
<head>
  <link href="css/styles.05e4dd86.css" rel="stylesheet">
  <script src="js/main.f4b855d8.js" defer="defer"></script>
</head>
<body>
  <h1>Hello World!</h1>
  <img src="img/picture.58b43bd8.png">
</body>
</html>

Open in StackBlitz

gpfsuwkq

gpfsuwkq3#

如果你对使用scss很满意,你可以这样做:
1.在项目的根目录下创建样式索引文件:“./src/styles/_index.scss”

@import './variables.scss';
@import './global.scss';
@import './sections.scss';

你想为你的网站导入scss,将其转换为css,然后做一些后期处理。最后,它将最终作为缩小的css文件在您的dist文件夹。这就是你需要在html页面中提供和导入的文件。
1.更改您的webpack配置:

const config  = {
  entry: ['./src/js/index.js', './src/styles/_index.scss'],
  output: {
    path: path.resolve(__dirname, './dist'),
    clean: true, // remove unused bundled files
  },
  module: {
    rules: [
      {
        test: /\.(js|jsx)$/i,
        loader: 'babel-loader',
        options: { outputPath: 'js/', name: 'main.js' }
      },
      {
                test: /\.scss$/,
                exclude: /node_modules/,
                use: [
                    {
                        loader: 'file-loader',
                        options: { outputPath: 'styles/', name: '[name].min.css' }
                    },
                    'sass-loader'
                ]
      },
      {
        test: /\.(eot|svg|ttf|woff|woff2|png|jpg|gif|otf)$/i,
        type: 'asset',
      },
    ],
  },
};

1.如果您进行构建,则应该有一个./dist/styles/_index.min.css文件。这是你需要送达的文件。如果你使用express,它看起来像这样:
app.use(express.static(path.join(__dirname, './styles')))
1.导入到你的HTML中,例如:<link rel="stylesheet" href="/_index.min.css"/>
注意:你需要考虑捆绑包的css文件大小。您可能希望每个页面都有一个_index.scss文件(代码拆分)。如果你仍然结束了太大的文件大小,你需要走得更远。对于每个页面,您可以有多个捆绑的style.min.css文件,您可以在滚动时延迟加载。
注意:你应该能够在你的webpack配置中使用css-loader,可能在file-loader和sass-loader之间。
你可以看看我在哪里做了类似的事情:https://github.com/BeeckmanThe1/uploader/blob/main/webpack.config.js
希望有帮助

相关问题