How to migrate from Svelte rollup.js to SvelteKit? - javascript

I've got a working svelte webapp running with rollup.js. On extending it, I learnt of SvelteKit and realise that it's a better match for my project. How can I migrate from rollup.js to SvelteKit?

Here is the updated URL for migrating to sveltekit from sapper:
https://kit.svelte.dev/docs/migrating
The key point you're probably looking for is to move configuration from your rollup.config.js to svelte.config.js
Preprocessor options are there under config.preprocess
So your svelte.config.js might end up looking like this:
import adapter from '#sveltejs/adapter-auto';
import preprocess from 'svelte-preprocess';
import image from "svelte-image";
/** #type {import('#sveltejs/kit').Config} */
const config = {
// Consult https://github.com/sveltejs/svelte-preprocess
// for more information about preprocessors
preprocess: [
preprocess(),
image(),
],
kit: {
adapter: adapter(),
// Override http methods in the Todo forms
methodOverride: {
allowed: ['PATCH', 'DELETE']
}
}
};
export default config;

Related

Apollo Client "Named export 'remove' not found"

I'm attempting to create an apollo client plugin for a Nuxt 3 application. It's currently throwing an error regarding a package called ts-invariant:
file:///Users/[my name]/Repositories/[project]/node_modules/#apollo/client/utilities/globals/fix-graphql.js:1
import { remove } from "ts-invariant/process/index.js";
^^^^^^
SyntaxError: Named export 'remove' not found. The requested module 'ts-invariant/process/index.js' is a CommonJS module, which may not support all module.exports as named exports.
CommonJS modules can always be imported via the default export, for example using:
import pkg from 'ts-invariant/process/index.js';
const { remove } = pkg;
at ModuleJob._instantiate (node:internal/modules/esm/module_job:124:21)
at async ModuleJob.run (node:internal/modules/esm/module_job:181:5)
at async Promise.all (index 0)
at async ESMLoader.import (node:internal/modules/esm/loader:281:24)
at async __instantiateModule__ (file:///Users/[my name]/Repositories/[project]/.nuxt/dist/server/server.mjs:4550:3)
[vite dev] Error loading external "/Users/[my name]/Repositories/[project]/node_modules/#apollo/client/core/index.js".
at file://./.nuxt/dist/server/server.mjs:3170:289
at async __instantiateModule__ (file://./.nuxt/dist/server/server.mjs:4550:3)
I feel like I know enough about this error to know it has something to do with how Nuxt 3 deals with ESM, but I can't be for certain.
Here's the nuxt plugin:
plugins/apollo-client.js
import { defineNuxtPlugin } from "#app"
import { ApolloClient, InMemoryCache } from "#apollo/client/core"
import { DefaultApolloClient } from "#vue/apollo-composable"
export default defineNuxtPlugin((nuxtApp) => {
const config = useRuntimeConfig()
const apolloClient = new ApolloClient({
uri: config.PUBLIC_API_ENDPOINT,
cache: new InMemoryCache(),
})
nuxtApp.vueApp.provide(DefaultApolloClient, apolloClient)
})
In a normal scenario, I might use the nuxt-apollo community module, but it is currently afk regarding a nuxt 3 port, so a plugin it is.
Here's some documentation I relied on for my plugin:
https://v4.apollo.vuejs.org/guide-composable/setup.html#vue-3
https://v3.nuxtjs.org/docs/directory-structure/plugins
Solved by including #apollo/client and ts-invariant/process into the nuxt build transpile like so:
// nuxt.config.js
// ...
build: {
postcss: {
postcssOptions: require('./postcss.config.js')
},
transpile: [
'#apollo/client',
'ts-invariant/process',
],
},
// ...
I think I've pinpointed the underlying issue. Apollo Client (3.5.10 at the time of writing early 2022) is using "module":"index.js" to declare the path of the ESM exports.
However it seems that Webpack 5 based bundlers do not support this. Using exports in the package.json fixes it for good for me.
You should upvote this feature request.
And here is my palliative until then, using a small script to alter the package.json.

NPM package: best practices and exposing multiple import paths

I created an NPM package that uses Webpack and Babel for transpiling/bundling.
In my package.json, I've got main set to "main": "build/index.js". And in my Webpack config, I have entry set to entry: { app: './src/index.js' }. My entry file is shown below.
Everything works fine when the package is installed. However, with this setup, two import paths are exposed for every helper:
This is a problem for editors that support auto imports, since they will sometimes auto import from 'my-package/build/utils/helper1' rather than the preferred path of 'my-package'.
So, two questions:
Is there any way to prevent the longer import path from being exposed?
What is considered best practice when creating NPM packages. Is my setup acceptable, or should I be doing something different?
Entry File:
import helper1 from './utils/helper1';
import helper2 from './utils/helper2';
export {
helper1,
helper2,
};
const myPackage = {
helper1,
helper2,
};
export default myPackage;
you can utilize Webpack resolve
I often use the first way:
export {
helper1,
helper2,
};
Recently, I found that we can use Object.freeze() to export. This is a good article.
I would suggest probably merge your helper1 and helper2 in one file and name it helpers, then you can put them in the class myPackage so that you then export them as a module like this
import myPackage from './utils/helper';
// OR import {helper1, helper2} from './utils/helpers';
export default class myPackage {
helper1,
helper2,
};
OR
import {myPackage} from './utils/helpers';
// OR import {helper1, helper2} from './utils/helpers';
module.exports.myPackage = (helper1, helper2) => {
this.helper1 = helper1;
this.helper2 = helper2;
};
I hope this helps.

Import types from .graphql into a .js file

I've searched something about import types from .graphql files. I’ve found graphql-import to import using # import something from 'something-else'. This works fine between .graphql files.
But what I’m trying to do is to import some types from generated.graphql from Prisma into a .js file.
For example:
I have this generated.graphql file from Prisma
"""generated.graphql file"""
type ItemWhereInput { ... }
type ItemConnection { ... }
...
I would like to import those two types ItemWhereInput and ItemConnection from generated.graphql file into items-types.js file
// items-types.js file
import gql from 'graphql-tag';
// I would like to make some kind of import ItemWhereInput and ItemConnection here
// Something like `import { ItemWhereInput, ItemConnection } from 'generated.graphql'`
...
const ItemWhereUniqueInput = gql`
input ItemWhereUniqueInput {
id: String!
}
`;
...
// And export ItemWhereInput and ItemConnection here
export default [Item, ItemInput, ItemWhereUniqueInput, ItemUpdateInput];
That way I could call makeExecutableSchema from graphql-tools and use those types in some place else
// items-query.js file
import { forwardTo } from 'prisma-binding';
const schema = `
items: [Item]!
item (where: ItemWhereUniqueInput!): Item
# And use it here
itemsConnection (where: ItemWhereInput): ItemConnection!
`;
const resolvers = {
items: forwardTo(‘db’),
item: forwardTo(‘db’),
itemsConnection: forwardTo(‘db’),
};
export default {
schema,
resolvers,
};
If it is somewhere else or there are something that could help, please, point me out.
Thanks.
You should be able to do the following:
During your build step, first, transform your generated.graphql file into a js file by
adding export default ` to the beginning of the file,
`); to the end of the file, and
renaming it to generated.js.
This way, you can import the file just as a js file in your development code:
// some other js file
/*
* notice the lack of .js, this should make it easier for your
* IDE to understand you're referencing the 'generated.graphql' file.
* If this is not possible in your code, you actually have to say
* .js here, not .graphql, because the file will be called .js after
* build.
*/
import generated from './generated';
console.log(generated);
You will see that schema is a string of the contents of the file pre-build-step.
It can now be used as typeDefs for makeExecutableSchema:
import { makeExecutableSchema } from 'graphql-tools';
import typeDefs from './generated';
import resolvers from './resolvers';
const schema = makeExecutableSchema({
typeDefs,
resolvers,
});
If you use a bundler and/or transpiler some additional work has to be done, to make sure the file is also run through these tools.
The project I've used this approach on only uses babel, with which it is a matter of:
using npm-watch instead of babel's --watch option to run the build script
(can be done in parallel)
running babel on all source .js files
running a custom script on all .graphql files, which:
adds the relevant code to the file, to make it valid js (in-memory)
programmatically runs babel on the result
saves it to the build destination with .js extension
Careful with large files though, as they are loaded to memory with this method!
Beware though, as this approach does not work with a bundler, for which you will have to either transform the file before running the bundler (and somehow still retain the old version, probably by naming the transformed version differently and deleting it after running the bundler), or find/create a Plugin doing this work for you.
Here are some options I found (quick google search): for webpack and Parcel.

How do I import 400+ modules, and iterate over them in my angular-cli project?

I am about to have 400+ models for use with js-data in my angular2 (angular-cli) app.
my project's structure is this:
- src/
- app/
- services/
- pipes/
- ui/
- data/
- store.ts
- models/
- model1.ts
- model2.ts
- ...
- model400.ts
In the store, I need to import, and add the mapping to the store.
The model files are actually just mapper configs for js-data 3.
currently, they look something like this:
// src/app/data/models/model1.ts
export default {
schema: {
name: 'model1',
properties: {
id: { type: 'integer' }
}
},
relations: {}
}
and my store currently looks like this:
// src/app/data/store.ts
import {
DataStore,
Mapper,
Record,
Schema,
utils
} from 'js-data'
import {HttpAdapter} from 'js-data-http'
declare var require: any
export const adapter = new HttpAdapter({
// Our API sits behind the /api path
basePath: '/api'
});
export const store = new DataStore({});
store.registerAdapter('http', adapter, { default: true });
import { model1Config} from './models/model1';
import { model2Config } from './models/model2';
import { model3Config } from './models/model3';
// at this point, I give up, cause this is more tedious
// than cutting grass with a finger nail clipper
store.defineMapper('model1', model1Config);
store.defineMapper('model2', model2Config);
store.defineMapper('model3', model3Config);
If there is anyway to iterate over every file in the models folder, that would be great.
angular-cli is supposed to eventually compile all the ts/js to a single js file, so I don't need to worry about anything that couldn't run on the client side.
(so, I have broccoli, and whatever other build tools are bundled with that, I just don't know if any of them would be useful to me for this situation)
You could use an index file, which you can use for your imports. for example in your models folder an index file which just exports every model for you like this:
// ...../models/index.ts
export * from './models/model1';
export * from './models/model2';
then in your other files you can import them like this:
import {model1Config, model2Config, model3Config } from "path/to/models/index";
...
You have to define the exports somewhere. Using a file which functions as a "export collection" saves you at least a lot lines of code (and a lot of time if you're using a good IDE).
Setting up the the index with your x-hundreds of models still is tedious. Maybe a little script with gulp could help.

How to ignore raw loader for testing webpack

I have some components with svg's loaded inline using webpack raw loader e.g...
import React, { Component } from 'react'
import svg from '!raw!../assets/images/logo.svg'
export default class Logo extends Component {
render() {
return (<a href={this.props.url} dangerouslySetInnerHTML={{__html: svg}} />)
}
}
When trying to test these components server side using tape, they fall over. If I have css modules included, it is no problem, I can use css-modules-require-hook but svg's will not work. So I really need a raw loader require hook or something like that.
require('babel-register');
require('css-modules-require-hook/preset');
/* tests after this can import components with css includes */
I tried using isomorphic-ensure but this did not work.
require('babel-register');
require('css-modules-require-hook/preset');
require('isomorphic-ensure')({
loaders: {
raw: require('raw-loader'),
raw: require('react-svgdom-loader')
},
dirname: __dirname
})
I get the following error:
Cannot find module '!raw!../assets/images/
If you're not using webpack for your tests then you could use the ignore-styles module.
You may have to configure it if you plan to use it with css-modules-require-hook as it will also also ignore CSS files by default. e.g:
require('ignore-styles').register(['.svg'])

Categories