I'm currently in the process of building a Vue UI component library for a company and in this process, I'm using webpack as the default bundler. I want to build the whole project into an npm package that then can be distributed via a private git package repository. The package distribution is up and running, but I can't seem to get components exported in the right way so it's possible to use in another project.
Versions for different tools used:
npm: 6.14.4
node: 12.17.0
yarn: 1.22.0
@vue/cli: 4.4.1
tsc: 3.9.5
Project structure is as follows:
public
src
- assets
| - css
| | - tailwind.css
| - fonts
| | - stylesheet.css
- component
| - LbButton
| | - LbButton.vue
| | - index.ts
| - Lbtag
| | - LbTag.vue
| | - index.ts
| - ...
- theme
| - index.ts
| - Theme.ts
- typedefs
| - types.ts
| - events.ts
| - model.ts
| - states.ts
- views
| - Home.vue
- App.vue
- index.ts
- main.ts
- plugin.ts
- shims-vue.d.ts
vue.config.js
tailwind.config.js
tsconfig.json
postcss.config.js
babel.config.js
package.json
The current setup contains the following configurations:
package.json
...
"main": "./dist/@livebackend/ui.common.js",
...
"scripts": {
"serve": "vue-cli-service serve",
"build": "vue-cli-service build --target lib --name @livebackend/ui src/index.ts ",
"test:unit": "vue-cli-service test:unit"
},
"files": [
"dist/*",
"src/*",
"public/*",
"*.json",
"*.vue",
"*.ts",
"*.js"
],
"dependencies": {
"@kazupon/vue-i18n-loader": "^0.5.0",
"@types/lodash": "^4.14.152",
"@types/vue-i18n": "^7.0.0",
"@types/vue-select": "^2.5.0",
"core-js": "^3.6.4",
"date-fns": "^2.14.0",
"lodash": "^4.17.15",
"v-calendar": "^1.0.6",
"vue": "^2.6.11",
"vue-class-component": "^7.2.3",
"vue-i18n": "^8.18.1",
"vue-infinite-loading": "^2.4.5",
"vue-property-decorator": "^8.4.1",
"vue-select": "^3.10.3",
"vuex": "^3.1.3",
"vuex-class": "^0.3.2"
},
"peerDependencies": {
"@vue/composition-api": "^0.6.7"
},
"devDependencies": {
"@types/chai": "^4.2.11",
"@types/mocha": "^5.2.4",
"@vue/cli-plugin-babel": "~4.3.0",
"@vue/cli-plugin-typescript": "~4.3.0",
"@vue/cli-plugin-unit-mocha": "~4.3.0",
"@vue/cli-plugin-vuex": "~4.3.0",
"@vue/cli-service": "~4.3.0",
"@vue/composition-api": "^0.6.7",
"@vue/test-utils": "1.0.0-beta.31",
"chai": "^4.1.2",
"node-sass": "^4.14.1",
"sass": "^1.26.5",
"sass-loader": "^8.0.2",
"style-loader": "^1.2.1",
"tailwindcss": "1.4.6",
"ts-loader": "^7.0.5",
"typescript": "~3.9.5",
"vue-style-loader": "^4.1.2",
"vue-template-compiler": "^2.6.11"
},
"version": "0.4.8"
}
tsconfig
{
"compilerOptions": {
"target": "esnext",
"module": "esnext",
"strict": true,
"declaration": true,
"importHelpers": true,
"moduleResolution": "node",
"noImplicitAny": false,
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
"sourceMap": true,
"baseUrl": ".",
"types": [
"webpack-env"
],
"paths": {
"@/*": [
"src/*"
]
},
"lib": [
"esnext",
"dom",
"dom.iterable",
"scripthost"
]
},
"include": [
"src/**/*.ts",
"src/**/*.vue"
],
"files": [
"src/vue-shims.d.ts"
],
"exclude": [
"node_modules"
]
}
vue.config.js
module.exports = {
publicPath: "./src",
devServer: {
proxy: "http://localhost:3000"
},
chainWebpack: config => {
config.plugins.delete("optimize-css");
},
configureWebpack: {
module: {
rules: [
{
resourceQuery: /blockType=i18n/,
type: "javascript/auto",
loader: "@kazupon/vue-i18n-loader"
}
]
}
}
};
tailwind.config.js
const settings = {
theme: {},
variants: {},
plugins: []
};
if (process.env.NODE_ENV === "production") {
settings.purge = ["./src/**/*.html", "./src/**/*.vue", "./src/**/*.jsx"];
}
module.exports = settings;
src/index.ts
export { default as Theme } from "./theme";
export { default as LbButton } from "./components/lbButton";
export { default as LbInputField } from "./components/lbInputField";
export { default as LbIconButton } from "./components/lbIconButton";
export { default as LbTag } from "./components/lbTag";
export { default as LbCard } from "./components/lbCard";
export { default as LbFB } from "./components/lbFB";
export { default as LbDatePicker } from "./components/lbDatePicker";
export { default as LbRadio } from "./components/lbRadio";
export { default as LbLoading } from "./components/lbLoading";
export { default as LbSlider } from "./components/lbSlider";
export { default as LbSwitch } from "./components/lbSwitch";
export { default as LbTable } from "./components/lbTable";
import plugin from "./plugin";
export default plugin;
main.ts
import Vue from "vue";
import VueI18n from "vue-i18n";
import vSelect from "vue-select";
import VCalendar from "v-calendar";
import "@/assets/css/tailwind.css";
import "@/assets/fonts/stylesheet.css";
import "vue-select/dist/vue-select.css";
import InfiniteLoading from "vue-infinite-loading";
import App from "./App.vue";
import messages from "./tranlations";
Vue.config.productionTip = false;
Vue.component("v-select", vSelect);
Vue.use(VCalendar, {
componentPrefix: "v"
});
Vue.use(VueI18n);
Vue.use(InfiniteLoading);
const i18n = new VueI18n({
locale: "en",
messages
});
new Vue({
i18n,
render: h => h(App)
}).$mount("#app");
If I need to post more files, please don't hesitate to ask.
When i bundle all of this up and include it in a project like import { LbButton } from "@livebackend/ui" I get an error that tells me that vue can't find type declarations or module. When i then try to import it from "@livebackend/ui/src" I get another error that tells me vue can't figure out what "@" means. I use "@" to find relative modules within the project.
Is there anyone that have had these problems before ?