Blocks cli v2 beta - how to use code from other directories?

Hey @Taylor_Savage and @Emma_Yeap,

The block cli v2 docs state the following:

Using code from other directories

The new CLI allows this method of code-sharing by allowing “sibling directories” outside the source directory to be bundled. Those other directories can include npm imports based on link or file.

What does this exactly mean? More specific setup / how-to instructions and an example repo demonstrating that would be very helpful.

Thanks,
Ronen
Eazyapps

Update, developing (another) private typescript app, tried to pull typescript code from folders outside of the app’s npm package folder, none of the following worked with the new cli:

  1. Include a typescript file using a relative path:

import MyButton from "../../mylib/ui/MyButton"

  1. Add mylib folder to the tsconfig.json paths setting.

  2. Add the mylib folder to the tsconfig.json rootDirs setting.

Note that I’ve raised the issue and asked for guidance of being able to easily share code between multiple Airtable apps more than a year ago. If that would have been straightforward and easy, airtable would have seen many more apps submitted to the marketplace, not only from eazyapps, but from many other app creators, to the benefit of the entire airtable community.

Hope this get’s resolved / documented soon, including how to treat @airtable/blocks (peer dependency?), another issue I raised more than a year ago.

Thanks,
Ronen

Hi @Ronen_Babayoff,

The code sharing means that you can import from files that are outside of the block’s directory (this was not possible with the previous CLI). There is no specific setup required, it should “just work”. Specifying the folder in tsconfig.json is not required.

Can you please give some more specific details about what errors you are encountering as well as double checking your CLI version with block --version?

Here’s a brief example (where hello-world-typescript-block is a block directory with package.json, .block, etc). I will see if we can publish this example as a standalone repo with all files included.

hello-world-shared/index.tsx

import React, {useState} from 'react';

export function Hello() {
    const [count, setCount] = useState(0);

    return (
        <div>
            <p>You clicked {count} times</p>
            <button onClick={() => setCount(count + 1)}>Click me</button>
        </div>
    );
}

hello-world-shared/package.json

{
    "name": "hello-world-shared",
    "version": "1.0.0",
    "description": "",
    "main": "index.jsx",
    "scripts": {
        "test": "echo \"Error: no test specified\" && exit 1"
    },
    "keywords": [],
    "author": "",
    "license": "ISC",
    "peerDependencies": {
        "react": "^16.9.0",
        "react-dom": "^16.9.0"
    }
}

hello-world-typescript-block/frontend/index.tsx

import {initializeBlock} from '@airtable/blocks/ui';
import React from 'react';

import {Hello} from '../../hello-world-shared';

function HelloWorldTypescriptApp() {
    // YOUR CODE GOES HERE
    return (
        <div>
            <Hello /> world! 🚀
        </div>
    );
}

initializeBlock(() => <HelloWorldTypescriptApp />);

hello-world-typescript-block/frontend/tsconfig.json

{
    "compilerOptions": {
        "module": "commonjs",
        "target": "es2018",
        "sourceMap": true,
        "allowSyntheticDefaultImports": true,
        "jsx": "react"
    },
    "exclude": ["node_modules"]
}

Hey @Emma_Yeap ,

I’m using the correct cli version. Just checked out your example and it works! :slight_smile: It works also when I add @airtable/blocks as a peer dependency to hello-world-shared/package.json, which used to be a problem when I tried a similar solution in the past.

Note that you do need to install all peer dependencies in the hello-world-shared folder or in one of it’s parent folders, in order for your example to work, which brings me to ask if the new cli supports npm workspaces? I haven’t checked it out my self yet.

I did check that:

  1. npm install --save ../hello-world-shared works and supports hot reloads and it does.

  2. npm link hello-world-shared works and supports hot reloads and it does (run npm link in hello-world-shared first).

This is a serious productivity booster.

I do recommend that your example monorepo will include @airtable/blocks a a peer dependency since most of us will want to build shared libraries on top of the airtable apps sdk.

I’d also recommend step by step instructions on how to set it up for local side by side development of the app and the library at the same time, since you’ll usually extend the library as part of a specific app development. npm link would be the recommended way to go here, instead of using relative paths when importing code or installing packages using relative paths to folders.

Thanks @Emma_Yeap!

A couple of updates / problems:

  1. Seems like npm link will only work with a main entry point in package.json of index.tsx, not index.jsx

  2. When using the exports field in package.json to export sub modules from hello-world-shared, cli recognizes the sub-modules, but visual studio code complains that it doesn’t find the import, which makes me not being able to work with the type when importing:

import {Hello} from 'hello-world-shared/ui';

Cannot find module 'hello-world-shared/ui' or its corresponding type declarations.ts(2307)

Hey @Emma_Yeap,

I cannot release the block with the new cli, block release gets stuck on:

Bundling... done
Uploading... Incomplete

block run does work.

Also, a couple of updates:

  1. npm workspaces do work

  2. Not recognizing the exports field in package.json is a typescript problem and will be supported in the next version of typescript. In the mean time, I’m using files instead to export what I want.

Hey @Ronen_Babayoff (I work with @Emma_Yeap)

First off - thank you for your feedback; it’s very helpful!

We published the example as a stand-alone git repo for easier access in the future.

I also just add @airtable/blocks as a peer dependency. We know that yarn workspaces work - but have not tested with npm workspaces. Glad to hear that npm workspaces also work!

Completely agreed that we also should add instructions how how to set up npm link here - especially since it works well with hot-reloads, I’ve gone ahead and done that - and added you to the readme! Expect to see this updated next week.

When you said that npm link is only working on index.tsx, do you mean it doesn’t work for index.jsx when not working in a typescript project - or do you mean when specifying the transpiled index.tsx target? (Aka - does npm link just not work at all in non-ts projects).

The sub-module import problem is interesting - makes sense that it’s on Typescripts side :+1:.

Regarding the release issue - could you share your code with us, or a minimal repro of the issue so that we can help debug?

Nevermind - was able to get it updated today!

2 Likes

Hey @SeanKeenan ,

Yes, saw the repo, thanks for mentioning me.

Regarding index.jsx, it didn’t work for me in a typescript project were both app and lib are typescript, in my specific setup - using npm link and npm workspaces. I don’t know if it will work in other setups.

Will try and repro the release problem and update topic once I do.

Thanks!

Hey @SeanKeenan,

Some more feedback - the example repo should use an airtable UI component, such as an airtable button, in order to make sure that everything works when using airtable as a peer dependency. Also, it should call a base function (i.e. print base.id, for example) to make sure that base dependent code can be in a shared library.

Thanks

Also, the example repo doesn’t work out of the box, here’s the error:

Error: Invalid hook call. Hooks can only be called inside of the body of a function component. This could happen for one of the following reasons:
1. You might have mismatching versions of React and the renderer (such as React DOM)
2. You might be breaking the Rules of Hooks
3. You might have more than one copy of React in the same app
See https://fb.me/react-invalid-hook-call for tips about how to debug and fix this problem.

Hey @SeanKeenan , so after forking @airtable/blocks and adding some logging to the new cli, turns out that the Uploading... Incomplete message is because the cli couldn’t find a block with that id.

That is because I accidently used the incorrect airtable api key. The new cli really needs to provide better feedback to the end user on those types of errors, which I assume are pretty common. The current cli also doesn’t provide proper feedback on this, see below for what the current cli provides.

This is the error that I logged from the new cli source code:

errors: [
  {      
    message: 'Could not find a block build with ID "bbdwGFk82bEs5S15g".',
    code: 'RESOURCE_NOT_FOUND'
  }
]

This is the error the current cli provides:

❌ Error: The requested endpoint "/v2/bases/appnDr2vV67PWUiRV/blocks/blkH2isnuKrkCue/builds/start" was not found.

Anyway, was able to release after setting the proper api key.

Thanks,
Ronen

Glad you were able to solve the problem with the Uploading... Incomplete error! I filed an issue in our internal tracker to make these errors better. This is pretty clearly a … non-ideal experience.

I also updated the example to use an Airtable/UI component - that’s an excellent call. It now prints the base name.

Finally - I figured out the issue with the example repo; it didn’t reproduce on my machine because I had a version of react higher up in the directory tree that was being referenced by both installations. I also put a brief explanation at the bottom of the readme as to why this was happening / why the fix is required.

Hope that helps!

1 Like

This topic was solved and automatically closed 15 days after the last reply. New replies are no longer allowed.