B
B
BonBon Slick2020-05-14 11:50:10
typescript
BonBon Slick, 2020-05-14 11:50:10

Vue + TypeScript css modules?

import stylesCommon from '@/assets/common/scss/common.scss'; // импортирует что надо,
//  но ситили применить нельзя т.к. модули неработают
import stylesFonts from '@fortawesome/fontawesome-free'; // пакет установлен, но импорт пустой!?

Vue.mixin(
    CSSModules({
        injectAttr: 'class',
        styles: {...stylesFonts, ...stylesCommon},
    }),
);

@Template
@Component({
    mixins: [CSSModules({
        injectAttr: 'class',
        styles: {...stylesFonts, ...stylesCommon},
    }),
    ],
    router,
})
class Main extends Vue {
    public mounted(): void {
        this.logWarning();
        console.log(stylesCommon);
        console.log(stylesFonts);
        console.log(CSSModules({
            injectAttr: 'class',
            styles: {...stylesFonts, ...stylesCommon},
        }),);
    }


conclusion
{h1: "h1", h2: "h2", h3: "h3", h4: "h4", h5: "h5", …}
main.ts?cd49:60 

// 2
{} __proto__: Object

// 3
{beforeCreate: ƒ}
beforeCreate: ƒ beforeCreate() __proto__: Object


{
        test: /\.css$/,
        use:  [
          MiniCssExtractPlugin.loader,
          {
            loader:  'css-loader',
            options: {
              importLoaders:  1,
              modules:        true,
              localIdentName: '[local]',
              sourceMap:      true,
            },
          },
        ],
      },
      {
        test: /\.scss$/,
        use:  [
          MiniCssExtractPlugin.loader, //'style-loader',
          {
            loader:  'css-loader',
            options: {
              importLoaders:  1,
              modules:        true,
              localIdentName: '[local]',
              sourceMap:      true,
            },
          },
          'sass-loader',
        ],
      },


{
  //  "compileOnSave": true,
  "compilerOptions": {
    "module": "es2020",
    "outDir": "./dist/",
    "sourceMap": true,
    "strict": true,
    "strictFunctionTypes": false,
    "noEmitHelpers": true,
    "experimentalDecorators": true,
    "importHelpers": true,
    "allowSyntheticDefaultImports": true,
    "emitDecoratorMetadata": true,
    "strictNullChecks": true,
    "noImplicitReturns": true,
    "noImplicitAny": false,
    "moduleResolution": "node",
    "target": "es6",
    "lib": [
      "dom",
      "es6",
      "es2020"
    ],
    "typeRoots": [
      "./node_modules/@types"
    ],
    "baseUrl": ".",
    "paths": {
      "~/*": [
        "./src/*"
      ],
      "@/*": [
        "./src/*"
      ]
    }
  },
  "exclude": [
    "backup",
    "dist",
    "build",
    "scripts",
    "acceptance-tests",
    "webpack",
    "jest",
    "src/setupTests.ts",
    "node_modules",
    "obj",
    "**/*.spec.ts"
  ],
  "include": [
    "src",
    "src/**/*.ts",
    "@types/**/*.d.ts"
  ]
}


I also tried this
but got an error
TS2339: Property '$route' does not exist on type 'Main'.

why did it overwrite
Vue.use(VueRouter);
export default new VueRouter({


Apparently, again, you need to trick a hand through one place or some kind of thing if I understood correctly.

Although I tried this , everything is cool, but this code is outdated 5-6 years ago.
import Template from '@/index.html?style=./index.scss'

throws errors
import * as Template from '@/index.html?style=./index.scss'

does not load styles
1 - global styles were imported, but they cannot be applied because modules don't work, why?
2- why is the icon import empty?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
B
BonBon Slick, 2020-05-14
@BonBonSlick

And so, after 5-6 hours I found a solution, and even more than one
1 - I used this plugin to inject it with a mixon in the main main.ts file.
2 - console.log console.log(CSSModules({as it should work
3 - it is important to specify the attr parameter injectAttr: 'class',to avoid using class="$style.container" the $styles parameter
4 - $style will not really work, in order for it to work, you need to prescribe some tricks with the .d.ts file

// 1. Make sure to import 'vue' before declaring augmented types
// 2. Specify a file with the types you want to augment
//    Vue has the constructor type in types/vue.d.ts
declare module 'vue/types/vue' {
    // 3. Declare augmentation for Vue
    interface Vue {
        // $style: { [key: string]: string }
        $style: any
    }
}

but I haven't been able to get $style to work yet, although modules and css should work somehow due to the mixin and the package mentioned above, and I also had to do additional tricks
5 - write the file to css
declare module '*.css' {
    import Vue, {ComponentOptions, FunctionalComponentOptions} from 'vue'

    interface Template2 {
        <V extends Vue, U extends ComponentOptions<V> | FunctionalComponentOptions>(options: U): U

        <V extends typeof Vue>(component: V): V
    }

    const template2: Template2;
    export = template2
}

6 - write the file to scss
declare module '*.scss' {
    import Vue, {ComponentOptions, FunctionalComponentOptions} from 'vue'

    interface Template {
        <V extends Vue, U extends ComponentOptions<V> | FunctionalComponentOptions>(options: U): U

        <V extends typeof Vue>(component: V): V
    }

    const template: Template;
    export = template
}

that is, 3 modules *.css / *.scss / *.html in .d.ts files, you can put them in one file, while it gives errors, I experiment
7 - add styles import Template from './app.pug?style=./app.scss'
8 - and the last thing I had to do was delete the folder builds, build/dist. After the new build, styles started working, but so far without
UPD modules - to make global and local styles work, I had to use 3+ plugins at once
import * as Template from '@/index.html?style=./index.scss'
import * as test from '@/index.scss';

//   миксин для инжекта local css которые подтянуты template-loader  '@/index.html?style=./index.scss'
Vue.mixin(
    CSSModules({
        // be careful, 'class' also use by 3-d parties libs classes
        injectAttr: 'class',
        // styles are merged with this.$style by default
        styles: {...stylesFonts, ...stylesCommon, ...test},
    }),
);

note that the $style parameter is not available, I was too lazy to dance with another module for TS, maybe later or someone will tell you how to do it.
"vue": "^2.6.11",
    "vue-class-component": "^7.2.3",
    "vue-css-modules": "https://github.com/BonBonSlick/vue-css-modules.git", // для инжекта стилей в $style
    "vue-template-loader": "^1.1.0", // для инжекта стилей в сборку, без етого css-modules не работает
    "vue-property-decorator": "^8.4.2", // для рендеринга

+ webpack package, typescript, etc.
Here's what's in the template
<h1 :class="[$style.hello, $style['text-danger']
    >
        can be used without mixin, but no global styles, $style still not accessible
      style "text-danger" is not available!
    </h1>
    <hr>
    <h2 class="hello">
        injected with template-loader and mixin, global and local styles available. modules
    </h2>

In general, while you have to use a mixin for injecting styles, otherwise where the first option is with the $style variable, the IDE does not give hints, maybe the TS Plugin mentioned below will solve the problem, but so far xs, and so I ruined a lot of time
h1 class="XD_i__hello text-danger">
          can be used without mixin, but no global styles, $style still not accessible
      style "text-danger" is not available!
    </h1> 
<h2 class="XD_i__hello _2qzp__text-danger">
        injected with template-loader and mixin, global and local styles available. modules
    </h2>

it took about 7 hours to dance with tambourines.
In fact, too much garbage had to be dug up, I said earlier that the guides and examples from the git are outdated.
Here are some of the resources that were used
  1. https://github.com/fjc0k/vue-css-modules
  2. https://github.com/ktsn/vue-template-loader/tree/m...
  3. https://github.com/ktsn/vue-template-loader
  4. https://github.com/mrmckeb/typescript-plugin-css-m...
  5. https://github.com/nuxt/typescript/issues/35
  6. https://habr.com/ru/post/458632/
  7. https://medium.com/@sapegin/css-modules-with-types...
  8. https://stackoverflow.com/questions/53997704/vue-t...
  9. https://dev.to/georgehanson/building-vuejs-applic...
  10. https://github.com/kaorun343/vue-typescript-exampl...
  11. https://github.com/kaorun343/vue-typescript-example-2
  12. https://github.com/Azure-Samples/vue-cosmosdb/tree...

https://github.com/wemake-services/wemake-vue-template
I'll go through it again later and see how to use fewer layers, tires, layers and other shit, for now we need to clean up the current hell into which the project turned after TS integration.
If anyone has better ideas, I would be grateful.
Although ,
<main :id="$style.app"
for now, it falls off. $style === undefined for this you need to add another line to the already existing css / scss / html
declare module '*.vue' {
    interface Vue {
        $style: any
    }

    export default Vue;
}

this is where the wildest magic happens. I don't have .vue files, everything compiles to dist folder.
I guess, webpack and packages, modules, plugins load and parse each other in a circle in a hidden order. So at some stage, when compilation is in progress extends Vueas templates, $styles is injected

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question