windicss / windicss-webpack-plugin

🍃 Windi CSS for webpack ⚡
https://windicss.org/integrations/webpack.html
79 stars 19 forks source link

Production environment, scoped generates different dom id and style id #114

Closed chengazhen closed 12 months ago

chengazhen commented 2 years ago

Describe the bug Production environment, scoped generates different dom id and style id; When I use the windicss plugin

To Reproduce Steps to reproduce the behavior:

  1. Clone repository '...'
  2. Run '....'
  3. See error

Expected behavior I want the custom style to be displayed normally

Screenshots image image

Additional context Add any other context about the problem here.

harlan-zw commented 2 years ago

Hi, can you provide some replication code

chengazhen commented 2 years ago

I tried to write a demo, but failed to reproduce, the problem is in the company project, I can only remove the scoped to solve

配置文件

const path = require('path')

const WindiCSSWebpackPlugin = require('windicss-webpack-plugin')

const { ElementPlusResolver } = require('unplugin-vue-components/resolvers')

const { defineConfig } = require('@vue/cli-service')

const { name } = require('./package')

function resolve(dir) {
  return path.join(__dirname, dir)
}

function isProduction() {
  return process.env.NODE_ENV === 'production'
}

// 项目名
module.exports = defineConfig({
  productionSourceMap: false,
  transpileDependencies: isProduction(),
  assetsDir: 'static',
  filenameHashing: true,
  publicPath: process.env.NODE_ENV === 'production' ? '/sr/' : '/',
  devServer: {
    hot: true,
    historyApiFallback: true,
    allowedHosts: 'all',
    port: 8848,
    headers: {
      'Access-Control-Allow-Origin': '*',
    },
  },
  // 自定义webpack配置
  configureWebpack: {
    resolve: {
      alias: {
        '@': resolve('src'),
      },
    },
    output: {
      // 把子应用打包成 umd 库格式
      library: `${name}-[name]`,
      libraryTarget: 'umd',
      chunkLoadingGlobal: `webpackJsonp_${name}`,
    },
    // auto import plugin
    plugins: [
      require('unplugin-auto-import/webpack')({
        imports: ['vue', 'pinia', 'vue-router'],
        dts: true,
      }),
      require('unplugin-vue-components/webpack')({
        resolvers: [ElementPlusResolver({ ssr: false })],
        dts: true,
      }),
      new WindiCSSWebpackPlugin(),
    ],
  },
  chainWebpack: (config) => {
    config.plugin('html').tap((args) => {
      // args[0].template = process.env.VUE_APP_HTML || 'public/index.html'
      args[0].title = '校长报告'
      args[0].template = isProduction()
        ? 'public/index_production.html'
        : 'public/index.html'
      return args
    })

    config.plugins.delete('prefetch')

    config.module
      .rule('svg')
      .exclude.add(resolve('src/assets/icons/svg'))
      .end()

    config.module
      .rule('icons')
      .test(/\.svg$/)
      .include.add(resolve('src/assets/icons/svg'))
      .end()
      .use('svg-sprite-loader')
      .loader('svg-sprite-loader')
      .options({
        symbolId: 'icon-[name]',
      })
      .end()
      .use('svgo-loader')
      .loader('svgo-loader')
      .options({
        name: 'removeAttrs', // 必须指定name!
        params: { attrs: 'fill' },
      })
      .end()

    config.plugin('define').tap((definitions) => {
      // 注入变量是为了解决path插件的问题
      Object.assign(definitions[0], {
        process: JSON.stringify({
          platform: null,
          version: null,
          GLOBAL_STRING: 'i am global var from vite.config.js define',
          GLOBAL_VAR: {
            test: 'i am global var from vue.config.js define',
          },
        }),
      })
      return definitions
    })
  },
  css: {
    loaderOptions: {
      scss: {
        additionalData: '@import "~@/assets/style/variables.scss";',
      },
    },
  },
})
nkxrb commented 1 year ago

Hi, can you provide some replication code

I'm having the same problem, it's a sporadic one. The same code is built multiple times, and errors may occur. I suspect that there is asynchronous processing logic between multiple loaders. After compiling, it is found that the source parameters of the two compilations are inconsistent in the loader(source) step.

source diffs:

// no windicss
<template>...</template>
<script lang="ts" setup>...</script>
<style lang="scss" scoped>...</style>

// has windicss
<template>...</template>
<script lang="ts" setup>...</script>
<style  lang="scss" scoped>\n...\n</style>

vue generate scopeId

 const id = hash(isProduction
        ? shortFilePath + '\n' + source.replace(/\r\n/g, '\n')
        : shortFilePath);

so vue-loader generate scopeId is different.

I tried fix it in #129 . Please help to see if it is possible .

harlan-zw commented 12 months ago

Very sorry for the delay, the fix has been pushed.