Vue3 / Vite: How to package components for publishing on npm - vue.js

I'm trying to export two web components in a public package on npm, using Vite with TypeScript.
Vite has a Library Mode (https://vitejs.dev/guide/build.html#library-mode) which works well. The ESM and UMD files are both being transpiled into my /dist directory. My question is how to export the web components in the entry point file.
I have an entry point file called export.js
import AwesomeHeader from './components/AwesomeHeader.vue'
import AwesomeFooter from './components/AwesomeFooter.vue'
export default { // I feel like the problem is here.
components: {
AwesomeHeader: AwesomeHeader,
AwesomeFooter: AwesomeFooter,
}
}
The idea is that I'll npm publish the project and use it like this.
npm i #sparkyspider/awesome-components #(ficticious example)
import {AwesomeHeader, AwesomeFooter} from '#sparkyspider/awesome-components' // does not find
(AwesomeHeader and AwesomeFooter are not found as exports in the node_module, even though the JavaScript files are referenced / found)
My package.json below:
{
"name": "#sparkyspider/awesome-components",
"version": "1.0.8",
"files": [
"dist"
],
"main": "./dist/awesome-components.umd.js",
"module": "./dist/awesome-components.es.js",
"exports": {
".": {
"import": "./dist/awesome-components.es.js",
"require": "./dist/awesome-components.umd.js"
}
},
"scripts": {
"dev": "vite",
"build": "vue-tsc --noEmit && vite build",
"serve": "vite preview"
},
"dependencies": {
"vue": "^3.0.5"
},
"devDependencies": {
"#vitejs/plugin-vue": "^1.2.2",
"#vue/compiler-sfc": "^3.0.5",
"typescript": "^4.1.3",
"vite": "^2.3.3",
"vue-tsc": "^0.0.24"
},
}

You are having object { component: ... } as default export, instead of exporting AwesomeHeader and AwesomeFooter, which you try to import.
export { AwesomeHeader, AwesomeFooter } in export.js will work.
More on export: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/export
And you can't destruct default export: https://stackoverflow.com/a/43987935/8810271

Related

Importing Fontawesome to VueJS

I've been trying to add Fontawesome to a Vue 3 project but it is breaking the app.
When I try to import the fontawesome nodemodules I get a network 504 failure.
In main.js
I try to import the library as follows:
/* import the fontawesome core */
import { library } from '#fortawesome/fontawesome-svg-core'
/* import font awesome icon component */
import { FontAwesomeIcon } from '#fortawesome/vue-fontawesome'
/* import specific icons */
import { faUserSecret } from '#fortawesome/free-solid-svg-icons'
This breaks the app and when I check the Network tab I see that my the path to these resources is set as:
http://localhost:5173/node_modules/.vite/deps/#fortawesome_free-solid-svg-icons.js?v=de8afee4
but this fails and creates a 504 Gateway Timeout
When I check in my node_modules folder I can see the #fortawesome folder it is there as expected.
I suspect it may be something to do with how .Vite is constructing the build that is wrong.
My package.json file looks like this:
{
"name": "litreach",
"version": "0.0.0",
"scripts": {
"dev": "vite",
"build": "vite build",
"preview": "vite preview"
},
"dependencies": {
"#fortawesome/fontawesome-svg-core": "^6.2.0",
"#fortawesome/free-brands-svg-icons": "^6.2.0",
"#fortawesome/free-regular-svg-icons": "^6.2.0",
"#fortawesome/free-solid-svg-icons": "^6.2.0",
"#fortawesome/vue-fontawesome": "^3.0.2",
"#popperjs/core": "^2.11.6",
"bootstrap": "^5.2.2",
"vue": "^3.2.45"
},
"devDependencies": {
"#vitejs/plugin-vue": "^3.1.2",
"sass": "^1.56.1",
"sass-loader": "^13.2.0",
"vite": "^3.1.8"
}
}
I deleted my node_modules folder and reinstalled and rebuilt again, but the same problem persists.

webpack 5 with babel build not exporting functions

I am trying to build and publish a react component to npm. I am using webpack 5 with babel. The build succeeds, but when I try use the component it is aparent that the component is not being exported as I get the following error in the console:
Warning: React.jsx: type is invalid -- expected a string (for built-in components) or a class/function (for composite components) but got: object. You likely forgot to export your component from the file it's defined in, or you might have mixed up default and named imports.
Check your code at App.js:41.
at App
My project structure looks like this:
- src/
- components/
- MyComponent.js
- styles/
- MyComponent.css
- index.js
- .babelrc
- package.json
- webpack.config.js
MyComponent.js contains the following:
import '../styles/MyComponent.css'
export default function MyComponentFunction() {
return (
<h1>Hello</h1>
)
}
My index.js file contains the following:
import MyComponentFunction from './components/MyComponent'
export default {
MyComponentFunction
}
My .babelrc file contains the following:
{
"presets": ["#babel/preset-env","#babel/preset-react" ]
}
My webpack.config.js contains the following:
const path = require('path')
module.exports = {
output: {
path: path.join(__dirname, '/dist'),
filename: 'index.bundle.js',
libraryTarget: 'umd'
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
use: {
loader:'babel-loader',
},
exclude: /node_modules/
},
{
test: /\.css$/,
use: [
'style-loader',
'css-loader'
],
exclude: /node_modules/
}
]
}
}
And my package.json (which includes lots of unused libraries) contains the following:
{
"name": "my-component",
"version": "0.0.1",
"description": "A react component ...",
"main": "dist/index.bundle.js",
"scripts": {
"build": "webpack --mode production",
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
...
},
"keywords": [
],
"author": "<Author>",
"license": "MIT",
"bugs": {
"url": "<github repo>"
},
"homepage": "<github repo>#readme",
"devDependencies": {
"#babel/core": "^7.19.6",
"#babel/plugin-proposal-export-default-from": "^7.18.10",
"#babel/plugin-syntax-dynamic-import": "^7.8.3",
"#babel/preset-env": "^7.19.4",
"#babel/preset-react": "^7.18.6",
"babel-loader": "^8.2.5",
"css-loader": "^6.7.1",
"eslint-webpack-plugin": "^3.2.0",
"file-loader": "^6.2.0",
"html-webpack-plugin": "^5.5.0",
"style-loader": "^3.3.1",
"webpack": "^5.74.0",
"webpack-cli": "^4.10.0"
},
"dependencies": {
"#react-three/drei": "^9.36.0",
"#react-three/fiber": "^8.8.10",
"react": "^18.2.0",
"three": "^0.145.0"
},
"peerDependencies": {
"react": "^18.2.0"
}
}
Why can I not import my component after it has been published? Which i'm trying to do like so:
import {MyComponentFunction} from 'my-component'
function App() {
return (
<>
<MyComponentFunction></MyComponentFunction>
</>
);
}
The reason you are facing this issue is that you have named the package as an exact match for this. The name must be unique.

How do i add vite.config.js file to my project?

I added vite to my project to run TailwindCSS. And now I am done and I wanted to build the project. But it only builds my index.html, not all my other pages (just using vanilla html and js). I know the line "npx tailwindcss init -p" to add the tailwind.config.js. Is there a command like this for Vite so i can say to build ./*.html?
{
"name": "tirisi",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "npm run build && vite preview"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"autoprefixer": "^10.4.2",
"postcss": "^8.4.8",
"tailwindcss": "^3.0.23",
"vite": "^2.8.6"
},
"dependencies": {
"#tailwindcss/line-clamp": "^0.3.1",
"daisyui": "^2.11.1"
}
}
From https://vitejs.dev/config/
The most basic config file looks like this:
// vite.config.js
export default {
// config options
}
Just create that file and paste that in. There's no vite equiv to npm init or tailwind init

vite.config.js => Uncaught SyntaxError: Cannot use import statement outside a module

I created a new repo with $ npm install vue-app and created some test components.
When i run the command $ npm run dev the application starts in localhost port 3000.
I try to add my component in a WP website. When i build the files and add to my theme, i receive the message:
Uncaught SyntaxError: Cannot use import statement outside a module
I found some documentation for webpack but not for vite.config.js.
Anyone can help?
vite.config.js
// vite.config.js
import vue from '#vitejs/plugin-vue'
export default {
plugins: [vue()]
}
package.json
{
"name": "vite-app",
"version": "0.0.0",
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"dependencies": {
"vue": "^3.0.5"
},
"devDependencies": {
"#vitejs/plugin-vue": "^1.2.3",
"#vue/compiler-sfc": "^3.0.5",
"vite": "^2.3.5"
}
}

React Select IE 11 - TypeError: Object doesn't support property or method 'assign'

What is wrong with this code ...IE 11 throwing
TypeError: Object doesn't support property or method 'assign'...chrome is behaving fine
import React from 'react';
import Select,{components} from 'react-select';
import { colourOptions } from '../react-select_Samples/data.js';
const Option = props => {
return ( <div>
<components.Option {...props}><input type="checkbox" checked={props.isSelected} onChange={() => null} />{props.label}
</components.Option></div> );
};
export class SampleDropdown extends React.Component {
render() {
return (
<Select
className="basic-single"
classNamePrefix="select"
defaultValue={colourOptions[4]}
isSearchable
name="color"
options={colourOptions}
components={{ Option}}
hideSelectedOptions={false}
isMulti
/>
);
}
}
here is package.json ...
it has following packages
"bootstrap(^3.4.1), es6-promise-promise(^1.0.0), react(^16.8.6), react-bootstrap(^0.31.5), react-dom(^16.8.6), react-router-bootstrap(^0.25.0), react-router-dom(^5.0.0), react-scripts(3.0.0), react-select(^2.4.3), rimraf(^2.6.3), whatwg-fetch(^3.0.0"
{
"name": "reports_react",
"version": "0.1.0",
"private": true,
"dependencies": {
"bootstrap": "^3.4.1",
"es6-promise-promise": "^1.0.0",
"react": "^16.8.6",
"react-bootstrap": "^0.31.5",
"react-dom": "^16.8.6",
"react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.0.0",
"react-scripts": "3.0.0",
"react-select": "^2.4.3",
"rimraf": "^2.6.3",
"whatwg-fetch": "^3.0.0"
},
"scripts": {
"start": "react-scripts start",
"build": "react-scripts build",
"test": "react-scripts test",
"eject": "react-scripts eject"
},
"eslintConfig": {
"extends": "react-app"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
]
}
When the React app is being build (dev or prod), spread operations are being transformed into Object.assign assignments.
A solution would be to use the babel-polyfill package and import right at the top of your entry point (index.js by default) to ensure correct functionality.
Another solution is to eject your react app using yarn eject, which will allow you to configure the build procedure of your app. You might have to delete the node_modules folder and reinstall your packages.
After ejecting you have to install the #babel/plugin-transform-object-assign package using yarn add #babel/plugin-transform-object-assign --dev and add the following to your package.json under the attribute babel:
{
...
"babel": {
"presets": ["react-app"],
"plugins": ["#babel/plugin-transform-object-assign"]
}
...
}
or the following to any babel configuration file:
{
"presets": ["react-app"],
"plugins": ["#babel/plugin-transform-object-assign"]
}
This will transform all Object.assign so they can be used inside unsupported environments (like IE11).
Ejecting is necessary for this method as facebook has the configurations for their create-react-app built-in to provide functioning defaults.