Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cannot dynamically import css in a static build #4237

Closed
steveworkman opened this issue Jul 13, 2021 · 4 comments
Closed

Cannot dynamically import css in a static build #4237

steveworkman opened this issue Jul 13, 2021 · 4 comments

Comments

@steveworkman
Copy link

steveworkman commented Jul 13, 2021

Describe the bug

When importing css or scss files (doesn't matter which format) in a vite application (framework does not matter here) you can import successfully in multiple different ways:

import './style.css'
import('./scss/sass.css');
const dyn = "dynamic"
import('./scss/' + dyn + '.css');

In the sample application, these three files all add styles to a single element. If all of these load, the element is blue. If only the first import loads, it is red.

When run locally with npm run dev you get a blue background. When you run npm run build and start a server in the dist folder you get the red background

Screenshot 2021-07-13 at 16 46 29

Screenshot 2021-07-13 at 16 47 11

The issue appears to be that, these files are compiled as pure .css files, but the application is looking for .js files for each of these hashes.

I've not found a suitable rollup plugin to correct this behaviour, and this is something that worked just fine with the Vue CLI and webpack, so I think it's a bug.

Reproduction

https://github.com/steveworkman/vite-scss-dynamic-test

System Info

npx: installed 1 in 1.481s

  System:
    OS: macOS 11.4
    CPU: (12) x64 Intel(R) Core(TM) i7-8850H CPU @ 2.60GHz
    Memory: 62.95 MB / 16.00 GB
    Shell: 5.8 - /bin/zsh
  Binaries:
    Node: 12.21.0 - ~/.nvm/versions/node/v12.21.0/bin/node
    npm: 6.14.11 - ~/.nvm/versions/node/v12.21.0/bin/npm
    Watchman: 2021.06.07.00 - /usr/local/bin/watchman
  Browsers:
    Chrome: 91.0.4472.114
    Chrome Canary: 93.0.4574.0
    Firefox Developer Edition: 90.0
    Safari: 14.1.1
    Safari Technology Preview: 15.0
  npmPackages:
    vite: ^2.4.2 => 2.4.2


### Used Package Manager

npm

### Logs

```shell
> @0.0.0 build /Users/steveworkman/code/vite-scss-dynamic-test
> vite build --debug

  vite:config bundled config file loaded in 64ms +0ms
  vite:config using resolved config: {
  vite:config   plugins: [
  vite:config     'alias',
  vite:config     'vite:dynamic-import-polyfill',
  vite:config     'vite:resolve',
  vite:config     'vite:html',
  vite:config     'vite:css',
  vite:config     'vite:esbuild',
  vite:config     'vite:json',
  vite:config     'vite:wasm',
  vite:config     'vite:worker',
  vite:config     'vite:asset',
  vite:config     'vite:define',
  vite:config     'vite:css-post',
  vite:config     'vite:build-html',
  vite:config     'commonjs',
  vite:config     'vite:data-uri',
  vite:config     'rollup-plugin-dynamic-import-variables',
  vite:config     'asset-import-meta-url',
  vite:config     'vite:import-analysis',
  vite:config     'vite:esbuild-transpile',
  vite:config     'vite:reporter'
  vite:config   ],
  vite:config   build: {
  vite:config     target: [ 'es2019', 'edge88', 'firefox78', 'chrome87', 'safari13.1' ],
  vite:config     polyfillDynamicImport: true,
  vite:config     outDir: 'dist',
  vite:config     assetsDir: 'assets',
  vite:config     assetsInlineLimit: 4096,
  vite:config     cssCodeSplit: true,
  vite:config     sourcemap: false,
  vite:config     rollupOptions: {},
  vite:config     commonjsOptions: { include: [Array], extensions: [Array] },
  vite:config     dynamicImportVarsOptions: { warnOnError: true, exclude: [Array] },
  vite:config     minify: false,
  vite:config     terserOptions: {},
  vite:config     cleanCssOptions: {},
  vite:config     write: true,
  vite:config     emptyOutDir: null,
  vite:config     manifest: false,
  vite:config     lib: false,
  vite:config     ssr: false,
  vite:config     ssrManifest: false,
  vite:config     brotliSize: true,
  vite:config     chunkSizeWarningLimit: 500,
  vite:config     watch: null
  vite:config   },
  vite:config   configFile: '/Users/steveworkman/code/vite-scss-dynamic-test/vite.config.js',
  vite:config   configFileDependencies: [ 'vite.config.js' ],
  vite:config   inlineConfig: {
  vite:config     root: undefined,
  vite:config     base: undefined,
  vite:config     mode: undefined,
  vite:config     configFile: undefined,
  vite:config     logLevel: undefined,
  vite:config     clearScreen: undefined,
  vite:config     build: {}
  vite:config   },
  vite:config   root: '/Users/steveworkman/code/vite-scss-dynamic-test',
  vite:config   base: '/',
  vite:config   resolve: { dedupe: undefined, alias: [ [Object] ] },
  vite:config   publicDir: '/Users/steveworkman/code/vite-scss-dynamic-test/public',
  vite:config   cacheDir: '/Users/steveworkman/code/vite-scss-dynamic-test/node_modules/.vite',
  vite:config   command: 'build',
  vite:config   mode: 'production',
  vite:config   isProduction: true,
  vite:config   server: { fs: { strict: undefined, allow: [Array] } },
  vite:config   env: { BASE_URL: '/', MODE: 'production', DEV: false, PROD: true },
  vite:config   assetsInclude: [Function: assetsInclude],
  vite:config   logger: {
  vite:config     hasWarned: false,
  vite:config     info: [Function: info],
  vite:config     warn: [Function: warn],
  vite:config     warnOnce: [Function: warnOnce],
  vite:config     error: [Function: error],
  vite:config     clearScreen: [Function: clearScreen]
  vite:config   },
  vite:config   createResolver: [Function: createResolver],
  vite:config   optimizeDeps: { esbuildOptions: { keepNames: undefined } }
  vite:config } +4ms
vite v2.4.2 building for production...
✓ 7 modules transformed.
dist/assets/favicon.17e50649.svg   1.49kb
dist/index.html                    0.45kb
dist/assets/sass.1c43ea22.css      0.05kb / brotli: 0.03kb
dist/assets/dynamic.d49ca673.css   0.05kb / brotli: 0.04kb
dist/assets/index.344921c7.css     0.28kb / brotli: 0.15kb
dist/assets/index.5309a613.js      3.34kb / brotli: 1.12kb


### Validations

- [X] Follow our [Code of Conduct](https://github.com/vitejs/vite/blob/main/CODE_OF_CONDUCT.md)
- [X] Read the [Contributing Guidelines](https://github.com/vitejs/vite/blob/main/.github/contributing.md).
- [X] Read the [docs](https://vitejs.dev/guide).
- [X] Check that there isn't already an issue that reports the same bug to avoid creating a duplicate.
- [X] Make sure this is a Vite issue and not a framework-specific issue. For example, if it's a Vue SFC related bug, it should likely be reported to https://github.com/vuejs/vue-next instead.
- [X] Check that this is a concrete bug. For Q&A open a [GitHub Discussion](https://github.com/vitejs/vite/discussions) or join our [Discord Chat Server](https://chat.vitejs.dev/).
@steveworkman
Copy link
Author

steveworkman commented Jul 14, 2021

Some more investigation - if these dynamically loaded css files are CSS Modules (with the filename of dynamic.module.css and sass.module.sass then they are imported correctly - though with the module hash as expected.

If you then switch css modules to use the global behaviour in the vite.config.js like this:

css: {
        modules: {
            scopeBehaviour: 'global'
        }
    }

You get the behaviour that I'm expecting in the ticket. I believe there is still an issue and that regular dynamic CSS imports should work like this

@finnmich
Copy link

finnmich commented Aug 13, 2021

I am experiencing the same (or very similar) issue when migrating a Vue-app to Vite.
I'm using a conditional import to set the theme of my application:

    if (light) {
        import('../styles/light/app.scss');
    } else {
        import('../styles/dark/app.scss');
    }

This work fine in dev, but in a production build I can see that the .css-files are generated but the application attempts to load a non-exsisting .js-file. Thus the styles are not loaded.

EDIT: The work-around posted above worked, but I also believe that this is still an issue.

@finnmich
Copy link

finnmich commented Sep 20, 2021

This now works without the module workaround for me as of vite 2.5.10

(Looks like it was fixed in 2.51: https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md#251-2021-08-24 )

Import with if/else does still not work, but it works with inlining the variable in the string

@steveworkman
Copy link
Author

Agreed - fixed by #3333

@github-actions github-actions bot locked and limited conversation to collaborators Oct 5, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants