Local extensions symlinks from /public to /src

When I’m working on a local extension from my source would it make sense to create symlinks from /public to my source?

At the moment when I’m working on an extension I have to make changes on the /public folder and then copy to source which negates a bit the whole point of having a source.

The right flow would be to make changes in the source and see them reflected in the browser while I’m developing.

As a bonus, I think we should try and follow some standards as it will improve the DX overall.
Make changes in src then build to dist and then commit src and publish dist.

The build step could be as easy or as complicated as one wants it to be. Going from just copying the files from the source to dist to doing a rollup/vite build with minification and others.

What do you think about this @george? The symbolic linking for now and improve the DX for extensions to follow the src->build->dist->publish flow

Yes good idea about the symlinks.

I was indeed struggling also with the issue and thinking how to keep the src and public web root in sync.

My initial thought was to use the extension updater to copy updated files automatically just as any other extensions updates.

That might be only not so handy during development as you are constantly changing the source files.

The only problem with symlinks is that currently we can’t see if the extension is “ in development” or installed as live extension. But will research if we can track this. It is easy to see in the package.json as local extensions starts with file:

1 Like

@george this is the simplest development workflow that I’m using involving js tooling and CI to develop and publish. Posting it here so you have it as reference to see how Wappler could help with this by simplifying the workflow.

  1. Create scoped folder structure
  2. Init Git repo in the folder and add remote
  3. .gitignore contents
  1. Run wappler form and enter extension details
  2. Write code in /public and test it in browser
  3. Once satisfied copy code to source folder.
  4. Install rollup as dev dependency. Could be any tool.
  5. Add simple rollup config.
export default {
    input: './index.js',
    output: {
        file: './dist/index.js'
    plugins: [
            targets: [
                { src: ['app_connect', 'style', 'package.json'], dest: 'dist' }
  1. Add extra package.json config.
"scripts": {
        "build": "rollup --config"
    "devDependencies": {
        "@rollup/plugin-terser": "^0.4.0",
        "rollup": "^3.20.0",
        "rollup-plugin-copy": "^3.4.0"
  1. Test build
  2. Create simple github action to publish to NPM on GH release.
    runs-on: ubuntu-latest
      - uses: actions/checkout@v3
      - uses: actions/setup-node@v3
          node-version: 16
          registry-url: https://registry.npmjs.org/
      - run: npm ci
      - run: npm run build    
      - run: npm publish ./dist --access public
          NODE_AUTH_TOKEN: ${{secrets.npm_token}}
  1. Commit and push to remote
  2. Create GH release and let GH action run to publish to npm.

So now the source is available in github and the distribution in npm.

Things that come to mind that could be improved:

  • Step 5) (writing code in /public) needs to be improved as we already spoke.

  • When building I have to create a /dist folder and copy the package.json into it which has the build script and dev dependencies which are not needed really in the published package. So maybe a npm install -omit dev is in order when installing via wizard a remote package?

  • Related to the previous one I have to publish the subfolder dist with npm publish ./dist --access public from my CI. This is needed as wappler will only install from root and not from a subfolder. Maybe check also if there is a dist folder with an app_connect subfolder and allow remote installations with that structure? Then I can just add a files node to package.json and skip copying the package.json, app_connect, and publishing from subfolder.

  • Related to the previous one I have doubts about having the source in the root of the directory. Wouldn’t it be better to have this /@scope?/extension_name/src/app_connect folder structure locally while leaving the package.json in /@scope?/extension_name/ ? This would allow more flexibility.

That is also a bit what we have in mind indeed.

The only thing with extensions repo was that we were thinking to add support for git submodules, so that you can commit your extension repo separately from the Wappler git manager

Now you have a nested git repo and I’m not sure how it will go if you also have a parent git repo for your whole project.

That could make sense indeed.

Right now this is how I’m doing it to avoid problems with the main app being also versioned. I have a separate Wappler project just for building extensions.

Code 20-03-2023 12.03.46 000338

I build in /extensions/app_connect (it just makes sense for me to have the src for all the extensions there). Hopefully there is no problem as SC uses and looks in /extensions/server_connect for SC extensions.

For each extension I have a github repo which are siblings so hopefully no problems there.

My only problem with this setup is that I also use this app to test each extension visually. So I have pages dedicated to each plugin. I’m also wary of what will happen if I version the main app with nested repos…so I haven’t.

@George just bumped into a symlinking issue that you will have to handle also.
Express will need to be able to serve static from src.

Fixed in Wappler 5.5.3

This topic was automatically closed after 46 hours. New replies are no longer allowed.