I have a library, let's call it my-lib. The packaged code contains some JS and type declarations for that code in /dist, as well as a number of SVG files in /assets:
my-lib
├── assets
│ ├── a.svg
│ ├── b.svg
├── dist
│ ├── index.d.ts
│ ├── index.mjs
│ ├── index.umd.js
├── LICENSE
├── package.json
My intention is to have the JS modules exported on the root of the package, my-lib, with the assets importable from my-lib/assets (when using an appropriate plugin for the user's framework and bundler, E.G. vite-plugin-svgr for React+Vite). This seems to work by default in a create-react-app project with Webpack using import { ReactComponent as A } from "my-lib/assets/a.svg"; and the right declaration file to appease TypeScript, but in a Vite project ends up throwing errors:
[vite] Internal server error: Missing "./assets/a.svg" export in "my-lib" package
The important bits of my package.json:
// package.json
{
"main": "./dist/index.umd.js",
"module": "./dist/index.mjs",
"types": "./dist/index.d.ts",
"files": [
"./dist",
"./assets"
],
// ...rest
}
Are there specific fields to use for non-JS assets in package.json? Is this simply an issue with bundler config?
Minimum reproducible example
I want to create a simple yarn package that can be installed by multiple local yarn projects using yarn add link:/path/to/package. Imagine the package of the package to be shared looks like this
├── package.json
├── tsconfig.json
└── src
├── generated
│ ├── abc.js
│ ├── abc.d.ts
│ └── def.js
│ └── def.d.ts
My goal is that abc and def should be accessible like this
import * from "myPackage/abc"
Currently if I install the above package with yarn add link:/path/to/package then I have to do
import * from "myPackage/src/generated/abc"
I'm a rookie on making typescript packages so forgive me. Can someone point me in the right direction here?
I've tried the suggestion here but it doesn't make a difference.
So it seems I need to set exports and typesVersions in package.json
"exports": {
"./": "./src/generated/"
},
"typesVersions": {
"*": {
"abc": [
"./src/generated/abc.d.ts"
],
"def": [
"./src/generated/def.d.ts"
],
}
},
I started working a lot with vue and started to use it in all the projects in the company where I work. And with that, I ended up creating some components, in general autocomplete, I know that there are many, I have already used some, but none have supplied all my needs. However, whenever I go to work on a new project and use the same component, either I recreates it, or I copy and paste it.
So I came to doubt How to create my component, upload to npmjs for whenever I use it, just give a npm install -save ..., and also be able to contribute a bit with the community.
update
With the release of vue-loader 15.x this answer will no longer work. Please use this instead https://medium.freecodecamp.org/how-to-create-a-vue-js-app-using-single-file-components-without-the-cli-7e73e5b8244f
Here is one way you can create/publish a Vuejs library/component from scratch.
As I am going to write down every step and command, make sure to follow the entire guide and you will be able to create and publish your own Vuejs component on NPM.
After you publish it, like most libraries you can install it using ex:
npm install --save your-component
And then import the component inside your app using
import something from 'your-component'
To start creating our first component, first create a folder called vuejs-hello-app (or any other name) and inside it, run:
npm init
Just hit enter until the interactive question ends and then npm will generate a file named package.json in that folder containing the following code.
(Note: I changed the description and version from 1.0.0 to 0.1.0 here is the result.)
{
"name": "vuejs-hello-app",
"version": "0.1.0",
"description": "vuejs library demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC"
}
After this, we'll need to install the dependencies for our library.
These dependencies are divided into two types: dependency and devDependency
dependency:
is the external library or libraries that our own component runs on. When someone installs your component, npm will make sure this dependency exists or gets installed first. Since we are creating a component for vue, we need to make sure vue is required. So, install it using:
npm install --save vue
devDependency:
is a bunch of libraries that we need only for development purposes. These libraries will help us build and/or transpile.
We install dev dependencies using the method above by adding the the suffix -dev to --save
Now, let us install the minimum dev dependencies we need for our component:
npm install --save-dev babel-core
npm install --save-dev babel-loader
npm install --save-dev babel-preset-env
npm install --save-dev cross-env
npm install --save-dev css-loader
npm install --save-dev file-loader
npm install --save-dev node-sass
npm install --save-dev sass-loader
npm install --save-dev vue-loader
npm install --save-dev vue-template-compiler
npm install --save-dev webpack
npm install --save-dev webpack-dev-server
At this point the libraries will be installed and the package.json will be updated to look like following.
{
"name": "vuejs-hello-app",
"version": "0.1.0",
"description": "vuejs library demo",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1",
"build": "webpack -p"
},
"author": "",
"license": "ISC",
"devDependencies": {
"babel-core": "^6.26.0",
"babel-loader": "^7.1.2",
"babel-preset-env": "^1.6.1",
"cross-env": "^5.1.1",
"css-loader": "^0.28.7",
"file-loader": "^1.1.5",
"node-sass": "^4.7.2",
"sass-loader": "^6.0.6",
"vue-loader": "^13.5.0",
"vue-template-compiler": "^2.5.9",
"webpack": "^3.10.0",
"webpack-dev-server": "^2.9.7"
},
"dependencies": {
"vue": "^2.5.9"
}
}
(note: I have added "build": "webpack -p" to build our lib with webpack)
Now, since our code needs to be built and transpiled, we need a folder to store the build version. Go ahead and create a folder inside our root folder and call it: dist and in the same place a configuration file for webpack and name it webpack.config.js
All of the files we have so far created are for configuring and stuff. For the actual app that people are going to use, we need to create at least two files inside our src/ directory.
A main.js and VuejsHelloApp.vue put them as:
./src/main.js and ./src/components/VuejsHelloApp.vue
I have mine structured like this:
dist
node_modules
src
main.js
components
VuejsHelloApp.vue
.babelrc
.eslintignore
.gitignore
.npmignore
.travis.yml
CONTRIBUTING
LICENSE
package.json
README.md
webpack.config.js
I will just go through the files listed and describe what each file does in-case anyone is curious:
/dist is where a build (transpiled), minified, non-ES6 version of your code will be stores
node_modules I think we know this already, let's ignore it
src/ this is root dir of your library.
.babelrc is where your babel options are kept, so add this to disable presets on modules
{
"presets": [
[
"env",
{
"modules": false
}
]
]
}
.eslintignore This is where you tell ESLINT to ignore linting so put this inside:
build/*.js
.gitignore
add files you want to ignore (from git)
.npmignore same as .gitignore for NPM
.travis.yml if you need CI check examples from travis and configure it
CONTRIBUTING not required
LICENSE not required
package.json ignore for now
README.md not required
webpack.config.js This is the important file that let's you create a build, browser compatible version of your code.
So, according to our app, here is a minimal example of what it should look like:
var path = require('path')
var webpack = require('webpack')
module.exports = {
entry: './src/main.js',
module: {
rules: [
// use babel-loader for js files
{ test: /\.js$/, use: 'babel-loader' },
// use vue-loader for .vue files
{ test: /\.vue$/, use: 'vue-loader' }
]
},
// default for pretty much every project
context: __dirname,
// specify your entry/main file
output: {
// specify your output directory...
path: path.resolve(__dirname, './dist'),
// and filename
filename: 'vuejs-hello-app.js'
}
}
if (process.env.NODE_ENV === 'production') {
module.exports.devtool = '#source-map'
module.exports.plugins = (module.exports.plugins || []).concat([
new webpack.DefinePlugin({
'process.env': {
NODE_ENV: '"production"'
}
}),
new webpack.optimize.UglifyJsPlugin({
sourceMap: true,
compress: {
warnings: false
}
}),
new webpack.LoaderOptionsPlugin({
minimize: true
})
])
}
Note that the important directives here are entry and output. You can check webpack docs to learn more if you want to fully customize your app.
But basically, we're telling webpack to get the ./src/main.js (our app) and output it as ./dist/vuejs-hello-app.js
Now, we are almost finished setting up everything except the actual app.
Go to /src/components/VuejsHelloApp.vue and dump this simple app, which will move a button right or left when you hover on it
<template>
<div>
<button #mouseover='move($event)'> I'm alive </button>
</div>
</template>
<script>
export default {
data () {
return {}
},
methods: {
move (event) {
let pos = event.target.style.float;
if(pos === 'left'){
event.target.style.float = 'right'
}else{
event.target.style.float = 'left'
}
}
}
}
</script>
<style scoped>
</style>
And not but not least, got to ./src/main.js and export your app like:
import VuejsHelloApp from './components/VuejsHelloApp.vue'
export default VuejsHelloApp
Now go to your package.json file replace the "main: "index.js", with "main": "src/main.js",
After this, simply run these commands to build and publish your app:
npm run build
git add .
git commit -m "initial commit"
git push -u origin master
npm login
npm publish
Importing and using the library.
If everything went smoothly, then simply install your app like this:
npm install --save vuejs-hello-app
And use it in vue like this:
<template>
<div>
<VuejsHelloApp> </VuejsHelloApp>
</div>
</template>
<script>
import VuejsHelloApp from 'vuejs-hello-app'
export default {
name: 'HelloWorld',
components: { VuejsHelloApp }
}
</script>
I made this app https://github.com/samayo/vuejs-hello-app while writing the answer, it might help to better understand the code
I'm totally lost at this point on how to get ESLint to install and function using Atom. So I'm going to post a step by step and would be really awesome if someone could help be get this working.
Atom: 1.19.5
Atom, linter 2.2.0
Atom, linter-eslint 8.2.1
I've uninstalled and reinstalled the Atom plugins and have disabled all other plugins besides those in Core and the 2 linters.
npm list -g --depth=0
All Global Installs:
├── create-react-app#1.0.4
├── create-react-native-app#1.0.0
├── eslint#4.6.1
├── express-generator#4.14.1
├── json-server#0.9.5
├── mocha#3.2.0
├── nodemon#1.11.0
├── npm#3.10.10
├── pushstate-server#2.2.1
├── react-native-cli#2.0.1
├── react-vr-cli#0.3.5
├── webpack#2.2.1
├── webpack-dev-server#2.3.0
└── yarn#0.21.3
These are the attempted steps I've done to get eslint to work in my Atom project:
npm install -g eslint
cd /into/project
eslint --init
? How would you like to configure ESLint? > User a popular style guide
? Which style guide do you want to follow? >Airbnb
? Do you use React? > y
? What format do you want your config file to be in? > JSON
Delete /node_modules
npm install
/project
/node_modules
.eslintrc.json
index.js
package.json
.eslintrc.json
{
"extends": "airbnb"
}
package.json
{
"name": "lint-test",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"devDependencies": {
"eslint": "^4.6.1",
"eslint-config-airbnb": "^15.1.0",
"eslint-config-rallycoding": "^3.2.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.3.0"
}
}
index.js
This is just a file trying to get some type of results from eslint
Errors
[Linter] Error running ESLint (Open developer console)
Configuration for rule "jsx-a11y/anchor-has-content" is invalid: Value "[object Object]" no (or more than one) schemas match.
So went to eslint-plugin-jsx #168
No errors are appearing in the Atom developer console. But also nothing is happening with the Linter in the Atom editor. I can type gibberish and nothing happens.
Running Debug
DEBUG=eslint:* eslint .
Debug results:
Cannot find module 'eslint-config-airbnb'
Referenced from: /Users/user/development/lint-test/.eslintrc.json
Error: Cannot find module 'eslint-config-airbnb'
Referenced from: /Users/user/development/lint-test/.eslintrc.json
at ModuleResolver.resolve (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/util/module-resolver.js:74:19)
at resolve (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:515:25)
at load (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:584:26)
at configExtends.reduceRight.e (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:421:36)
at Array.reduceRight (native)
at applyExtends (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:403:28)
at loadFromDisk (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:556:22)
at Object.load (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config/config-file.js:592:20)
at Config.getLocalConfigHierarchy (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config.js:226:44)
at Config.getConfigHierarchy (/Users/user/.nvm/versions/node/v6.9.5/lib/node_modules/eslint/lib/config.js:180:43)
At this point I'm assuming it's trying to read from the global not local
eslint eslint-config-airbnb error #465
updated .eslintrc.json to "extends": "eslint-config-airbnb",
Now again nothing is happening, run debug again
DEBUG=eslint:* eslint .
Still can't find the module
Try suggestions in Configuring Atom editor with eslint
At this point I'm still running into Cannot find module 'eslint-config-airbnb'
Followed npm eslint-config-airbnb
ran all the commands
New local package.json
"devDependencies": {
"eslint": "^4.6.1",
"eslint-config-airbnb": "^15.1.0",
"eslint-plugin-import": "^2.7.0",
"eslint-plugin-jsx-a11y": "^5.1.1",
"eslint-plugin-react": "^7.3.0"
}
npm install -g eslint-config-airbnb
New Global Modules
├── create-react-app#1.0.4
├── create-react-native-app#1.0.0
├── eslint#4.6.1
├── eslint-config-airbnb#15.1.0
├── eslint-plugin-import#2.7.0
├── UNMET PEER DEPENDENCY eslint-plugin-jsx-a11y#6.0.2
├── eslint-plugin-react#7.3.0
├── express-generator#4.14.1
├── install-peerdeps#1.1.3
├── json-server#0.9.5
├── mocha#3.2.0
├── nodemon#1.11.0
├── npm#3.10.10
├── pushstate-server#2.2.1
├── react-native-cli#2.0.1
├── react-vr-cli#0.3.5
├── webpack#2.2.1
├── webpack-dev-server#2.3.0
└── yarn#0.21.3
So now I can run DEBUG=eslint:* eslint . and can get some results. However nothing ever runs in Atom.
Results:
/Users/user/development/lint-test/index.js
1:1 error Definition for rule 'jsx-a11y/href-no-hash' was not found jsx-a11y/href-no-hash
1:7 error 'config' is assigned a value but never used no-unused-vars
1:24 error Unable to resolve path to module '../something' import/no-unresolved
1:39 error Missing semicolon semi
✖ 4 problems (4 errors, 0 warnings)
1 error, 0 warnings potentially fixable with the `--fix` option.
At this point I'm out of ideas on how to get Atom to actually work with eslint...
uncheck the setting "Use global ESLint installation" in linter-eslint of ATOM will make it correct
Without digging into the issue and finding specific point of failure I decided on a fresh start.
Delete global node modules.
Delete all NON core Atom plugins AND themes.
uninstall Atom.
reinstall Atom.
install ESLint and supporting dependencies only.
Doing that I was able to run ESLint with no issues. My assumption in all of this is there was a conflict in a plugin or theme. From there installing my core tool plugins was successful.
I've a node project which works with ES6 and serves an angular project in public folder:
├── public
│ ├── client.js
│ └── .eslintrc
├── server.js
└── .eslintrc
I would like to use airbnb extension in server and angular extension in client side so I've tried:
.eslintrc:
{
"parser": "babel-eslint",
"extends": "airbnb"
}
public/.eslintrc:
{
"extends": "angular"
}
The result is that in client.js rules for airbnb are being applied too. Is it possible to invalidate parent .eslintrc?
You can add root: true to the top of any config to stop ESLint from searching parent folders for config files. So you should update your public/.eslintrc and add top level property "root": true.