Aurelia using featherjs dependency failing to properly import feathers-socketio - aurelia

How do you import featherjs-socketio using the technique common in Aurelia projects. A previous question helped me past the second dependency, but the last one seems to have the same fate as the first without a similar workaround. Aurelia using featherjs depency failing to properly import
This is what I have:
in the build file aurelia.json
"dependencies": [
{
"name": "socket.io-client",
"path": "../node_modules/socket.io-client/dist/socket.io.min"
},
{
"name": "feathers-client",
"path": "../node_modules/feathers-client/dist",
"main": "feathers"
},
{
"name": "feathers-socketio",
"path": "../node_modules/feathers-socketio",
"main": "client"
},
"aurelia-binding",
In the app.js
import io from 'socket.io-client';
import feathers from 'feathers';
import socketio from 'feathers-socketio';
export class App {
constructor() {
this.message = 'Hello World!';
console.log("startup");
const socket = io('http://localhost:3030');
const app = feathers()
.configure(socketio(socket));
}
}
The error looks like this:
Starting 'readProjectConfiguration'...
Finished 'readProjectConfiguration'
Starting 'processMarkup'...
Starting 'processCSS'...
Starting 'configureEnvironment'...
Finished 'processCSS'
Finished 'processMarkup'
Finished 'configureEnvironment'
Starting 'buildJavaScript'...
Finished 'buildJavaScript'
Starting 'writeBundles'...
Tracing app...
{ uid: 8,
name: 'writeBundles',
branch: false,
error:
{ [Error: ENOENT: no such file or directory, open '/Users/steve/project/src/feathers-socket-commons/client.js']
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/Users/steve/project/src/feathers-socket-commons/client.js',
moduleTree: [ 'feathers-socketio/lib/client' ],
fileName: '/Users/steve/project/node_modules/feathers-socketio/lib/client.js' },
duration: [ 0, 281071327 ],
time: 1484922063672 }
Once it gets into processing the dependency it seems to be having path confusion looking for dependencies in featherjs-socketio. I asked a previous question about the feathers dependency which is resolved, but not sure what to do with this one.
feathers-socket-commons is listed in the node modules, but it seems to be looking in my project folder so that is why I'm assuming it is confused on path, or simply not a client library? Strange because the examples show using this node module, but examples also show using 'feathers' instead of 'feathers-client'. This is the client example given in feathers-socketio:
Client use
import io from 'socket.io-client';
import feathers from 'feathers/client';
import socketio from 'feathers-socketio/client';
const socket = io('http://path/to/api');
const app = feathers()
.configure(socketio(socket));
SOLUTION Thanks to the marked answer below.
aurelia.json changes to:
"dependencies": [
{
"name": "socket.io-client",
"path": "../node_modules/socket.io-client/dist/socket.io.min"
},
{
"name": "feathers-client",
"path": "../node_modules/feathers-client/dist",
"main": "feathers"
},
"aurelia-binding",
app.js becomes:
import io from 'socket.io-client';
import feathers from 'feathers-client';
export class App {
constructor() {
this.message = 'Hello World!';
console.log("startup");
const socket = io('http://localhost:3030');
const app = feathers().configure(feathers.socketio(socket));
}
}

you don't need to install feathers-socketio it is included in feathers-client among other plugins.
configure(socketio(socket))
becomes:
configure(feathers.socketio(socket))
according to the feathers-socketio

Related

ESM library generated with rollup-plugin-postcss throws Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'

We are maintaining an internal library which is exporting ESM modules using Rollup. We have just recently switched to using CSS modules, which we have set with rollup-plugin-postcss. We want to inject these styles into the head rather than have an external file.
Our built bundle generates the ESM file with:
import styleInject from '../node_modules/style-inject/dist/style-inject.es.js';
Our consuming library then fails with
Uncaught Error: Cannot find module '../node_modules/style-inject/dist/style-inject.es.js'
I would expect the ESM export to import styleInject from 'style-inject' and style-inject to be included in the package-lock.json as a dependency. What is the correct way of using CSS Modules and injecting into the head for the consumer of a library?
rollup.config.js
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import babel from '#rollup/plugin-babel';
import json from '#rollup/plugin-json';
import postcss from 'rollup-plugin-postcss';
import pkg from './package.json';
import fg from 'fast-glob';
import path from 'path';
export default [
{
input: 'src/index.js',
external: external(),
output: [
{
name: '#my/packageName',
file: pkg.module,
format: 'es',
sourcemap: true,
},
],
plugins: [
{
name: 'watch-external',
async buildStart() {
const files = await fg(['src/index.d.ts', 'playground/**/*']);
for (let file of files) {
this.addWatchFile(path.resolve(file));
}
},
},
json(),
postcss({
modules: true,
}),
babel({
exclude: /node_modules/,
babelHelpers: 'runtime',
babelrc: false,
presets: [
[
'#babel/preset-env',
{
modules: false,
useBuiltIns: 'entry',
corejs: 3,
targets: {
ie: 11,
},
},
],
'#babel/preset-react',
],
plugins: [
'#babel/plugin-transform-runtime',
'#babel/plugin-proposal-class-properties',
'#babel/plugin-proposal-export-namespace-from',
],
}),
commonjs(),
],
},
];
function external() {
const { dependencies = {}, peerDependencies = {} } = pkg;
const externals = [
...Object.keys(dependencies),
...Object.keys(peerDependencies),
];
return id =>
// match 'lodash' and 'lodash/fp/isEqual' for example
externals.some(dep => id === dep || id.startsWith(`${dep}/`));
}
There is a bug in the library where the import is relative rather than being the module name.
There is an open pr, but the library looks like it is no longer being maintained. There are two recommended solutions in the comments:
String replace the built output
Add a custom rollup plugin to do this
This is not a bug at all. It works properly because stylesInject is just a function from 'styles-inject' package, so we can allow it to be bundled. But it is not bundled because most likely you have this setting in your rollup.config.js:
external: [
/node_modules/
]
So, replace it with a code bellow and it will work:
external: (id) => {
if (/style-inject/.test(id)) return false;
if (/node_modules/.test(id)) return true;
return false;
},
also, you can write a regexp for it instead
You need to do 2 things:
Add style-inject dependency in package.json
"dependencies": {
"style-inject": "^0.3.0"
},
Add following plugin to rollup.config.js
const plugins = [
...
{
/**
* - https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
* - https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in
*/
name: 'Custom Rollup Plugin`',
generateBundle: (options, bundle) => {
Object.entries(bundle).forEach((entry) => {
// early return if the file we're currently looking at doesn't need to be acted upon by this plugin
if (!entry[0].match(/.*(.scss.js)$/)) {
return;
}
// this line only runs for .scss.js files, which were generated by the postcss plugin.
// depending on the use-case, the relative path to style-inject might need to change
bundle[entry[0]].code = entry[1].code.replace(
/\.\.?\/[^\n"?:*<>|]+\/style-inject\/dist\/style-inject.es.js/g,
'style-inject',
);
});
},
}
];
References:
https://github.com/egoist/rollup-plugin-postcss/issues/381#issuecomment-880771065
https://lightrun.com/answers/egoist-rollup-plugin-postcss-esm-library-generated-with-rollup-plugin-postcss-throws-cannot-find-module-node_modulesstyle-in

How to deal with the problem of TS2367 error after the replacement code?

I use rollup-replace as the variable switch of the builder in the project, but I have encountered a problem when using it with TypeScript, and I always give me errors like this:
semantic error TS2367: This condition will always return'true' since the types'boolean' and'string' have no overlap.
I will write code like this in my code
// a.ts
import Prod from './prod';
import Pre from './pre';
If(process.env.PROD === ’true’){
console.log(‘is prod’);
Prod.init();
} else {
console.log(‘is pre’);
Pre.init();
}
// rollup.config.js
import typescript from 'rollup-plugin-typescript2';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import replace from '#rollup/plugin-replace';
export default [
{
input: 'src/a.ts',
output: { file: 'dist/a.js', format: 'iife' },
plugins: [
replace({ values: { 'process.env.PROD': JSON.stringify(true) }, preventAssignment: true }),
resolve({ browser: true }),
commonjs(),
typescript(),
]
}
]
In the above build code, replace needs to precede resolve, because it is necessary to use replace to avoid useless JS from being imported into the bundle file.
Who can help me solve this meaningless error message?
In the rollup document, I found the advanced usage of treeshake.moduleSideEffects, which talked about the ability I want to achieve.
import typescript from 'rollup-plugin-typescript2';
import resolve from '#rollup/plugin-node-resolve';
import commonjs from '#rollup/plugin-commonjs';
import replace from '#rollup/plugin-replace';
export default [
{
input: 'src/a.ts',
output: { file: 'dist/a.js', format: 'iife' },
plugins: [
replace({ values: { 'process.env.PROD': JSON.stringify(true) }, preventAssignment: true }),
resolve({ browser: true }),
commonjs(),
typescript(),
],
treeshake: {
moduleSideEffects: false, // Prune unused pure external imports
},
}
]

Uncaught Error: 'target' is a required option - Svelte

I'm building an NPM package for Svelte. With this package I export a couple of simple components:
import SLink from './SLink.svelte';
import SView from './SView.svelte';
export { SLink, SView };
This is before bundling them to a minified version using rollup.
Rollup config:
module.exports = {
input: 'src/router/index.ts',
output: {
file: pkg.main,
format: 'umd',
name: 'Router',
sourcemap: true,
},
plugins: [
svelte({
format: 'umd',
preprocess: sveltePreprocess(),
}),
resolve(),
typescript(),
terser(),
],
};
package.json (minus unnecessary info):
{
"name": "svelte-dk-router",
"version": "0.1.29",
"main": "dist/router.umd.min.js",
"scripts": {
"lib": "rollup -c lib.config.js",
},
"peerDependencies": {
"svelte": "^3.0.0"
},
"files": [
"dist/router.umd.min.js"
],
}
When I publish the package and test it, I get this error:
Uncaught Error: 'target' is a required option
at new SvelteComponentDev (index.mjs:1642)
at new Home (App.svelte:5)
at Z (router.umd.min.js:1)
at N (router.umd.min.js:1)
at new t.SView (router.umd.min.js:1)
at create_fragment (App.svelte:5)
at init (index.mjs:1476)
at new App (App.svelte:5)
at main.js:7
at main.js:9
Which seems to be something to do with mounting the component as target is used to mount:
const app = new App({ target: document.body })
The odd thing is, SLink on it's own works fine, mounts as it should etc., it's just SView that doesn't work.
SLink:
<script lang="ts">
import { writableRoute, changeRoute } from '../logic';
export let name: string = undefined,
path: string = undefined,
query: Record<string, string> = undefined,
params: Record<string, string> = undefined;
let routerActive: boolean;
writableRoute.subscribe(newRoute => {
if (newRoute.path === '*') return;
const matches = (path && path.match(newRoute.regex)) || newRoute.name === name;
routerActive = matches ? true : false;
});
</script>
<div
on:click={() => changeRoute({ name, path, query, params })}
class={routerActive ? 'router-active' : ''}>
<slot />
</div>
SView:
<script lang="ts">
import { writableRoute } from '../logic';
let component: any;
writableRoute.subscribe(newRoute => (component = newRoute ? newRoute.component : null));
</script>
<svelte:component this={component} />
I've tried the components uncompiled, as per these docs, but then the imports don't work.
Anyone have any idea how I can work around this issue?
I recently ran into this problem. I was setting up a new page and forgot the defer keyword on the script. I had:
<script src="/app/public/build/bundle.js"></script>
and it needed to be
<script defer src="/app/public/build/bundle.js"></script>
Notice the missing defer.
All components in a Svelte tree need to be compiled with the same Svelte compiler (i.e. same node_modules/svelte) all at once. This includes components from external libs like what you are trying to achieve. This is what is explained in the docs you've linked.
The main field of the package.json will expose the compiled components, for usage in a non Svelte app.
You also need a svelte field to expose the uncompiled version of the components, for consumption by a Svelte app. You can still export multiple Svelte components from a .js file.
package.json
{
"name": "svelte-dk-router",
"version": "0.1.29",
"main": "dist/router.umd.min.js",
"svelte": "src/index.js",
"scripts": {
"lib": "rollup -c lib.config.js",
},
"peerDependencies": {
"svelte": "^3.0.0"
},
"files": [
"dist/router.umd.min.js"
],
}
src/index.js
import SLink from './SLink.svelte';
import SView from './SView.svelte';
export { SLink, SView };
rollup-plugin-svelte will pick up the svelte field in your lib's package.json, so that import of Svelte components resolve correctly.
I don't know about your issue but I was getting the same error message for this reason:
In the template.html file located in the src folder, I removed the element that has the #sapper ID and replaced the %sapper.html% code inside the body tag. The next thing to do was to change the render target to the document.body, in the client.js file located in the src folder. I forgot to do this step and this was causing that error message.

How to create my own component library based on Vuetify

I want create my component library based on Vuetify and publish on npm.
Vuetify has already vue-plugin standard installation and use vuetify-loader, I think was a more complex scenario than plain HTML component.
For example, I want create my Login Form, my Article Page, my default calendar picker with preset values.
There's a standard way or guide to do this or a sample to do that?
I use last version of vuetify (2.0.7)
I just got it working for Vue3/Vuetify3. In a nutshell (using pnpm, vite, typescript, Vue plugin):
Create the component as a new project:
pnpm create vue#latest
-> your-plugin
-> Typescript
-> ESLint
cd <project>
echo auto-install-peers = true > .npmrc
pnpm add -D vuetify rollup-plugin-typescript2
Then remove all the components and make your own component instead.
Create src\components\index.ts and src\YourPlugin.ts
src\components\index.ts
export {default as YourComponent} from "./YourComponent.vue"
src\YourPlugin.ts
import type { App } from "vue"
import { YourComponent } from "./components"
export default {
install: (app: App) => {
app.component("YourComponent", YourComponent)
}
};
vite.config.ts
Add to the imports:
import vuetify from 'vite-plugin-vuetify'
import typeScript2 from "rollup-plugin-typescript2"
Add to the plugins:
vuetify({
autoImport: true,
}),
typeScript2({
check: false,
include: ["src/components/*.vue"],
tsconfigOverride: {
compilerOptions: {
sourceMap: true,
declaration: true,
declarationMap: true,
}
},
exclude: [
"vite.config.ts"
]
})
Add a new section build to the defineConfig:
build: {
cssCodeSplit: false,
lib: {
entry: "./src/YourPlugin.ts",
formats: ["es", "cjs"],
name: "CommonVtfyPlugin",
fileName: format => (format == "es" ? "index.js" : "index.cjs"),
},
rollupOptions: {
external: ["vue", "vuetify/lib"],
output: {
globals: {
vue: "Vue",
vuetify: "Vuetify",
'vuetify/components': 'VuetifyComponents',
'vuetify/directives': 'VuetifyDirectives'
}
}
}
},
dist\index.d.ts
I have not figured out how to generate this on yet. But this is a generic stand in:
declare const _default: any;
export default _default;
package.json
Add this:
"type": "module",
"exports": {
".": "./dist/index.js"
},
"types": "./dist/index.d.ts",
"files": [
"dist"
],
You can use it in any Vue project by importing it as a plugin:
import YourComponent from 'your-plugin'
app.use(YourComponent)
No guarantees on how optimized that is (feedback welcome).. but it works (tm)..
A more detailed answer can be found pnpm monorepo: how to set up a simple reusable (vue) component for reuse? (any updates will primarily be updated in that answer as well, if any)

Automatically generating ambient module declarations

Given these 2 typescript files
api/Token.ts
interface Token {
code: string
}
export default Token
and index.ts
export * from './api/Token'
tsc 1.5 with the --declarations switch will generate two .d.ts files (with similar content)
api/Token.d.ts
interface Token {
code: string;
}
export default Token;
and index.d.ts
export * from './api/Token';
Running grunt-dts-bundle with the following options
dts_bundle: {
release: {
options: {
name: 'my-module',
main: 'index.d.ts'
}
}
}
will generate an ambient module declaration file my-module.d.ts with the following content
declare module 'my-module' {
export * from './api/Token';
}
However this declaration does not compile due to : Import or export declaration in an ambient module declaration cannot reference module through relative module name.
How can I automatically generate an ambient module declaration for the two typescript files above ?
EDIT
Please follow latest updates on https://github.com/Microsoft/TypeScript/issues/2262
I've recently written a blog post about this. To summarize, you can use autodts if you replace index.ts with api.ts, containing the following:
export {default as Token} from './api/Token';
Make sure api.ts is in the same place as the api directory (next to, not inside it).
Then you need a package.json file:
{
"name": "api",
"version": "1.0.0",
"main": "dist/api.js",
"scripts": {
"preinstall": "npm install autodts",
"postinstall": "autodts link",
"prepublish": "tsc && autodts generate"
},
"typescript": {
"definition": "index.d.ts"
},
"dependencies": {
"autodts": "~0.0.4"
},
"devDependencies": {
"#lib/autodts-generator": "~0.0.1",
"typescript": "~1.5.3"
}
}
It's important that the package name api matches the file api.ts and directory api. This way both Node.js and the TypeScript compiler will look in the same places when using your package.
Finally, you need a tsconfig.json file:
{
"compilerOptions": {
"declaration": true,
"module": "CommonJS",
"target": "es5",
"outDir": "dist"
},
"files": [
"api.ts"
]
}
Now npm install will compile your package and produce a bundled index.d.ts file as defined in the definition setting in package.json.
To use your package, you can do something like:
/// <reference path = "api/index.d.ts" />
import {Token} from 'api';
class foo {
key: Token;
}
You can use autodts link to keep the reference path up to date, check the blog post and/or autodts docs for that.
The resulting index.d.ts contains:
/// <reference path="index.ref.d.ts" />
declare module 'api/Token' {
interface Token {
code: string;
}
export default Token;
}
declare module 'api' {
export { default as Token } from 'api/Token';
}
index.ref.d.ts and api.js are blank.