3

I'm currently building an external component library using Vue 3 + Vite. I'm using 3rd party component and style, but the style doesn't apply when I used it in my main project. It used to work before when I use Vue 2 + Vue CLI.

My component library project looks like this:

enter image description here

and here's the detail for my code

vite.config.js

import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [vue()],
  build: {
    lib: {
      entry: resolve(__dirname, 'src/main.js'),
      name: 'custom-lib',
      fileName: 'custom-lib',
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
})

package.json

{
  "name": "custom-lib",
  "private": true,
  "version": "0.0.0",
  "type": "module",
  "files": [
    "dist"
  ],
  "main": "./dist/custom-lib.umd.cjs",
  "module": "./dist/custom-lib.js",
  "exports": {
    ".": {
      "import": "./dist/custom-lib.js",
      "require": "./dist/custom-lib.umd.cjs"
    }
  },
  "scripts": {
    "build": "vite build"
  },
  "dependencies": {
    "moment": "^2.29.4",
    "vue": "^3.2.41",
    "vue-datepicker-next": "^1.0.2"
  },
  "devDependencies": {
    "@vitejs/plugin-vue": "^3.2.0",
    "sass": "^1.56.0",
    "sass-loader": "^13.1.0",
    "vite": "^3.2.3"
  }
}

src/components/Datepicker.vue

<template>
  <DatePicker
    :id="id"
    v-model:value="inputVal"
    value-type="date"
    type="date"
    :format="dateFormat"
    :placeholder="dateFormat"
    :disabled="disabled"
    input-class="mx-input"
  />
</template>

<script>
import DatePicker from 'vue-datepicker-next';
import moment from 'moment';

export default {
  name: 'Datepicker',
  components: {
    DatePicker
  },
  props: {
    id: {
      type: String,
      required: true
    },
    modelValue: null,
    dateFormat: String,
    disabled: Boolean
  },
  computed: {
    inputVal: {
      get() {
        if (this.modelValue) {
          return moment(this.modelValue).toDate();
        }
        return null;
      },
      set(val) {
        let strVal = undefined;
        let m = moment(val);
        if (m.isValid()) {
          strVal = m.format("YYYY-MM-DDTHH:mm:ss");
        }

        this.$emit('update:modelValue', strVal);
      }
    }
  }
};
</script>

<style lang="scss">
@import "vue-datepicker-next/scss/index.scss";
</style>

src/main.js

import Datepicker from './components/Datepicker.vue';

export {
    Datepicker
}

My Datepicker style not working in my main project, is there something missing from the config?

Bilal
  • 3,191
  • 4
  • 21
  • 49
James
  • 408
  • 5
  • 20
  • You mean the style does apply to your component. But when you use it as a library on another project, the style does not apply, right? – Duannx Nov 11 '22 at 10:15
  • Usually, you need to import your component style into your main project to make the style work. – Duannx Nov 11 '22 at 10:17
  • Use the following plugin - [vite-plugin-css-injected-by-js](https://github.com/Marco-Prontera/vite-plugin-css-injected-by-js) - if you can't get it working, I will make you an example in a answer. – flydev Nov 11 '22 at 13:38
  • @James you might try [this answer](https://stackoverflow.com/a/71071183) – Bilal Nov 12 '22 at 15:22
  • @Duannx yes, when I used it as components in my main project. the style working, but when I put the components in my library and used components from there. the style not working. I already tried to import the style in my main project, the style not applying too. I'm importing like this: `@import "custom-lib/dist/style.css"` – James Nov 14 '22 at 08:07
  • @flydev where do you put this `cssInjectedByJsPlugin` ? – James Nov 14 '22 at 08:22
  • @James Can you reproduce your problem on stackblitz.com? – Duannx Nov 14 '22 at 09:16

1 Answers1

3

As I was suggesting in comment, you can use vite-plugin-css-injected-by-js

  1. Add the plugin to your component project:

npm i vite-plugin-css-injected-by-js --save

  1. Add the plugin to vite config of your custom component:
import { resolve } from 'path'
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import cssInjectedByJsPlugin from 'vite-plugin-css-injected-by-js' // 

// https://vitejs.dev/config/
export default defineConfig({
  plugins: [
    vue(),
    cssInjectedByJsPlugin() // 
  ],
  build: {
    lib: {
      entry: resolve(__dirname, 'src/main.js'),
      name: 'custom-lib',
      fileName: 'custom-lib',
    },
    rollupOptions: {
      external: ['vue'],
      output: {
        globals: {
          vue: 'Vue'
        }
      }
    }
  }
})

It should work without hassle.

See it on Stackblitz:

you can go in test folder (cd test) and run yarn dev to launch the preview.

Result:

enter image description here

flydev
  • 4,327
  • 2
  • 31
  • 36