【问题标题】:Vue and Webpack tree shaking, sideEffects and CSS: CSS of unused components being loadedVue 和 Webpack 摇树、sideEffects 和 CSS:正在加载的未使用组件的 CSS
【发布时间】:2021-03-12 21:30:53
【问题描述】:

我们正在尝试找出在使用 Webpack 的 Vue 单文件组件中处理 CSS 摇树的正确方法。

在 package.json 中,我有:"sideEffects": ["*.css", "*.less","*.vue" ],这似乎在阻止 Vue 组件不应该加载时正常工作。但是,来自 SFC 的每个 <style> 标记都已加载到页面上。

我们加载 SFC 的方式是从一个列出一堆导出的 NPM 包中加载的,例如

export blah from 'blah.vue';
export blah2 from 'blah2.vue';
export blah3 from 'blah3.vue';

即使在我们的 JavaScript 中我只有import { blah3 } from 'a-npm-package';,它也包含了所有三个样式。由于我们有很多 Vue 组件,这导致页面中添加了很多未使用的 CSS。

我们如何防止这种情况发生?必须有一种更好、更动态的方式来处理样式,而不是仅仅将它们全部转储到页面中,即使只使用了其中的 1/10?

谢谢

【问题讨论】:

    标签: css vue.js webpack vuejs2


    【解决方案1】:

    您可以使用MiniCssExtractPlugin 来摇树CSS。此外,如果您使用的是 scss 或 sass,您也可以添加这些加载器。

    // webpack.config.js (production)
    const path = require('path')
    const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    module.exports = {
      mode: 'production',
    
      entry: path.resolve('src/index.js'),
    
      output: {
        filename: '[name].js',
        path: path.resolve('dist'),
      },
    
      module: {
        rules: [
          {
            test: /\.jsx?$/,
            loader: 'babel-loader',
            exclude: /node_modules/,
          },
          {
            test: /\.css$/,
            exclude: /node_modules/,
            use: [
              // Extract the css to file
              MiniCssExtractPlugin.loader,
              // Handle import of `.css` files in your app
              'css-loader',
            ],
          },
        ],
      },
      plugins: [
        // Extract all css into a separate file
        new MiniCssExtractPlugin({
          filename: '[name].css',
        }),
      ],
    }
    

    【讨论】:

      【解决方案2】:

      我是这样拆分上一个项目的:

      import Vue from 'vue'
      import VueRouter from 'vue-router'
      import LoginPage from '../views/LoginPage.vue'
      
      Vue.use(VueRouter);
      
      const Calendar = () => import(/* webpackChunkName: "calendar" */ '../pages/Calendar')
      const MyProfile = () => import(/* webpackChunkName: "myprofile" */ '../pages/MyProfile')        
      
      const pages = {
        Calendar,
        MyProfile,
      }
      
      const lazyLoader = (name) => pages[name];
      const routes = [
        {
          path: '/',
          name: 'LoginPage',
          component: LoginPage
        },
        {
          path: '/app/calendar',
          name: 'Calendar',
          component: lazyLoader('Calendar')
        },
        {
          path: '/app/my-profile',
          name: 'MyProfile',
          component: lazyLoader('MyProfile')
        }
      ]
      
      const router = new VueRouter({
        mode: 'history',
        base: process.env.BASE_URL,
        routes
      })
      
      export default router
      

      【讨论】:

      【解决方案3】:

      如果组件只是有时需要,那么延迟加载它们是减少混乱的好方法。

      例如:

      const MyComponent = () => import(/* webpackChunkName: "MyComponent" */'../components/MyComponent');
      

      https://vuedose.tips/dynamic-imports-in-vue-js-for-better-performance/

      在这种情况下,您还可以将插件合并到您的 Webpack 配置中以帮助管理庞大的代码,例如 MiniCSSExtractPlugin

      【讨论】:

      • 感谢您的回答,但赏金专门用于摇树,而不是延迟加载
      【解决方案4】:

      如果你使用lazy loading components?会怎样

      带有style标签的组件只有在需要时才会被加载。

      您可以使用lazy loading routes. 对路由执行相同操作

      【讨论】:

      • 感谢您的回答,但赏金专门用于摇树,而不是延迟加载
      猜你喜欢
      • 2023-03-15
      • 2020-10-18
      • 2019-03-04
      • 2016-11-17
      • 2018-03-03
      • 1970-01-01
      • 2021-11-13
      • 2016-07-01
      • 2018-03-09
      相关资源
      最近更新 更多