Giter VIP home page Giter VIP logo

standards's Introduction

Nextcloud developement standards

This repository aims to discuss development standards we have at Nextcloud We discuss ideas and once a concensus has been found, we write it down for transparency

standards's People

Contributors

skjnldsv avatar

Stargazers

 avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

standards's Issues

Supported node/npm versions

Hello,

Let's get this repo started.

Something I wanted to have discussed is our current de facto "standard" that is spreading in the ecosystem where we lock down node/npm versions to one specific major version each. I've seen people fall into the trap of using the node/npm that comes with their setup. Sometimes that is a bit older, sometimes it's the latest LTS version, other times it's bleeding edge. Npm warns you when you use an incompatible engine, and so if people clone one of our repos and install npm dependencies, they are greeted with a flood of warnings. Even worse, some repos don't even build with the latest versions of node.

nextcloud-libraries/nextcloud-axios#424 is an example.

Some questions off the top off my head

  1. Who gets to decide what versions of Node/npm "we" support?
  2. Are specific node/npm versions a recommendation or requirement?
  3. Does it even make sense to define this globally? We are also not locking down php versions. Everyone is free to run anything from PHP7.4 to PHP8.1 mostly. Some repos have to restrict this based on their special needs. Calendar still support Nextcloud 21+, so we still allow PHP7.3. Talk's main branch only targets the upcoming server release, so it is PHP7.4.
  4. Why can't we allow wider ranges for repos where it doesn't cause any known problems? If server only works with Node >=14<=16 then I'm fine with that. But if the axios lib can work with 18 as well then I don't see why it needs to be disabled. The restriction would be artificial.

Single repository for app and related npm package

Single repository for app and related npm package

This decision have been taken after the following discussion: #3

Initial idea

Sometimes it may be useful to provide an npm package to ease the integration with an existing app or to provide reusable code.

For example text markdown rendering is reused in collectives and might be useful to other apps.

Splitting the text app into a package and the app would create extra overhead in particular for backporting fixes - but also in terms of testing, issue tracking etc. - we'd probably end up with a nextcloud/text repo and a nextcloud/nextcloud-text repo. Sounds confusing and might be asking for trouble.

So instead we'd like to build the @nextcloud/text npm package from the source code of the text app. This adds a new build target. In our case it also adds some tooling because we want to build esm packages - but it's far less intrusive than splitting the app in two repos.

The package.json file so far does not contain the fields relevant to packaging ('files', 'main', 'module', 'type') etc. We added them and we have a working prototype here: nextcloud/text#2386 So far it builds the package nicely and we can use it in collectives.

There's a bunch of metadata that is used both by the package and the app:

  • name in package.json
  • Version number in package.json
  • dependencies in package.json
  • Readme.md

Drawbacks

Seeing the issues with nextcloud/text#2614, it's a bad idea to have them both in the same root.

  1. A package.json is representing a single element.
  2. Having both the app AND the package is actually going to mess with the dependencies and make things messy in my opinion.

We took the decision to not share package.json

Recommendations:

  1. Do not serve multiple ressources from the same package.json
  2. you can have related apps and package in the same repo
  3. Make sure we have two separate packages for those use cases.
    Here is an example on how it could look like:
    MyApp/
    ├─ node_modules/
    ├─ dist/
    │  ├─ myapp.esm.js
    │  ├─ myapp.cjs.js
    │  └─ myapp.js
    ├─ js/
    │  └─ myapp-main.js
    ├─ src/
    │  ├─ package/
    │  │  ├─ node_modules/
    │  │  ├─ lib/
    │  │  │  └─ index.js
    │  │  └─ package.json
    │  └─ main.js
    ├─ package.json
    │
    

Release automation

It would be nice to have the changeling generation and npm releases handled through GitHub actions or at least have some docs on which steps to take. This showed up to be an issue when trying to release @nextcloud/moment but is the same for other npm packages we have in our organisation. Only @nextcloud/vue seems to be automated/documented currently.

NPM packages for apps

Sometimes it may be useful to provide an npm package to ease the integration with an existing app or to provide reusable code.

For example text markdown rendering is reused in collectives and might be useful to other apps.

Splitting the text app into a package and the app would create extra overhead in particular for backporting fixes - but also in terms of testing, issue tracking etc. - we'd probably end up with a nextcloud/text repo and a nextcloud/nextcloud-text repo. Sounds confusing and might be asking for trouble.

So instead we'd like to build the @nextcloud/text npm package from the source code of the text app. This adds a new build target. In our case it also adds some tooling because we want to build esm packages - but it's far less intrusive than splitting the app in two repos.

The package.json file so far does not contain the fields relevant to packaging ('files', 'main', 'module', 'type') etc. We added them and we have a working prototype here: nextcloud/text#2386 So far it builds the package nicely and we can use it in collectives.

There's a bunch of metadata that is used both by the package and the app:

  • name in package.json
  • Version number in package.json
  • dependencies in package.json
  • Readme.md

I'll go through them one by one:

Name

The package is currently called @nextcloud/text. nextcloud-libraries/webpack-vue-config#338 proposes a change to the webpack-vue-config to remove the @nextcloud prefix from the app name when building the js assets. This way naming the package that goes along with APP @nextcloud/APP would work nicely.

Version number

Once the package is released i do not see any reason to not follow the version numbering of the app. We're currently using 0.x.0 numbers to indicate this is work in progress.

Dependencies

The package only covers parts of text functionality. Therefor it only needs some of texts dependencies. We turned all other dependencies into devDependencies. This prevents additional dependencies for the package and still works nicely for building the app.

Readme.md

The Readme is used to present the app on apps.nextcloud.com and as part of a package it's show on npm: https://www.npmjs.com/package/@nextcloud/text

From my point of view this is the strongest conflict in reusing metadata between the app and the package. The audience for an app is different from the one of the package.

However i think this could be solved by adding a small section on how to use the package. Knowing what the app is about and how development works is relevant for both the app and the package anyway.

Cypress selectors library

We had the discussion at various moments over the last years and quite frequently over the last months in the server team.

Context

As components/e2e/visual testing gets more and more powerful and practical, we wand to move away from selenium for a much easier testing process like cypress.

Goals

Offer an easy way to select various elements of Nextcloud without having to manually write down all selectors and generating duplicates across the Nextcloud apps/repos

Suggestion

Create a versioned library @nextcloud/cypress where devs can specify selectors for specific apps.
Selectors would then be importable in your tests files.

import { UploadButton } from `@nextcloud/cypress/files/24`
import { StartCallButton } from `@nextcloud/cypress/spreed/14`

cy.getNc(UploadButton).should('exist')
cy.getNc(StartCallButton).click()

Any opinions? Questions?

cc @nextcloud/server @juliushaertl @nickvergessen @danxuliu

Supported node/npm versions

Following #1

Which version of node and/or npm should I support in my app or library

At Nextcloud, we support security-maintained LTS versions of Node and Npm.
You can check the schedule in https://endoflife.date/nodejs

  1. Make sure to have your engines section up-to-date in your package.json as we have scripts to update them once a version become unmaintained.

    You can specify the version of node that your stuff works on
    You can also use the "engines" field to specify which versions of npm are capable of properly installing your program. For example:

    {
      "engines": {
        "node": "^20.0.0",
        "npm": "^10.0.0"
      }
    }
  2. Please also use appropriates workflows like you can find in our templates repository since they use the engines block to properly setup node and npm
  3. Engines expose the minimum version we support. As a dev, you are free to use newer releases, but testing and releases must be done against those versions.
    Warnings might be thrown in the console, but they will not impact the process.
  4. We recommend devs to use NVM to quickly switch between versions

Schedule

schedule

Changelog

  • 30-06-2022 - First draft of this issue. Moving from Node14 to Node 16 exceptionally because node 14 ships npm6 by default
  • 15-01-2024 - Updated all nodes versions to 20 and npm to 10

Unify transpilation of nextcloud JS libraries

Goal

  1. Unify the way Javascript and Typescript libraries are transpiled and provided.
  2. Prevent compatibility issues of (3rd party) dependencies and out supported browsers.

Background

Currently there are a bunch of libraries provided as is without being transpiled by babel,
while other apps are transpiled using the nextcloud babel configuration.
(This might origin from when we had supported ES5 browsers, but all supported browsers now support ES6+)
Libraries are then bundled by apps which transpile their sources and might or might not transpile their dependencies.

So currently most apps exclude babel transpilation on node_modules, as done by the default @nextcloud/webpack-vue-config: https://github.com/nextcloud/webpack-vue-config/blob/53df7bbe61e4a6d960c1d13e63597ce361f3795d/rules.js#L39

But this might lead to issues when bundling for browsers, as now all dependencies, event 3rd party, are required to be already transpiled to work with currently supported browsers. Meaning app developers will have to check each 3rd party dependency if it is transpiled to some supported version.


libs do not pass anything through babel (despite having an unnecessary babel.config.js present)

Transpiled by babel:

Options

Doing nothing is not an option, as we provide the webpack configuration doing no transformation on app dependencies, while at the same time providing libraries which might be not compatible with our target browsers is very inconsistent.

Transpile our libraries using Babel

  • No huge build time for apps, but only increase library build time (a bit)
  • Users can use the libraries without worrying about supported browser
    • But still need to check other 3rd party dependencies (e.g. exclude only /node_modules/@nextcloud)

Do not transpile[1] libraries

  • A lot faster build times
  • Small bundle size (no polyfills within every library but only in the final app)
  • Probably better treeshaking (
  • No need to rebuild after browserslist is updated
  • We need to enforce apps to transpile all dependencies

footnotes

[1]: Typescript libraries would still need to be transpiled so a target version of Javascript has to be defined, this should be the supported version of the current node version, for Node 16 this is es2022.


Origin: This issue came up in the discussion of nextcloud-libraries/nextcloud-l10n#535 ( @skjnldsv )

Splitting shipped and installed apps

Following some discussions that I've seen happening in the past and recently too

Proposal

On every setup, dev AND prod, having a read-only and read-write apps folders should be the preferred and official way.

$ ls -la
drwxr-xr-x   47 admin users    4096 26 nov.  15:27 3rdparty
drwxr-xr-x   31 admin users    4096 18 oct.  15:34 apps
drwxr-xr-x    2 admin users    4096 17 août  16:06 apps2
drwxr-xr-x    2 admin users    4096 29 nov.  09:52 config

Reasoning

  • From a dev perspective, it avoid any script from server potential editing folders/files that are not part of the server repository
  • From a production perspective:
    • Cleaner folder structure
    • Makes it possible to install updated of shipped apps (shipped stays in apps, update goes into apps2
    • Anything else?

Questions

  • Show a warning in setup page ?
  • Strict forbid of new setups if no apps config ?
  • Enforce it straight away without the admin configuring anything ?
  • What would be the apps folder name ? apps2 ? custom_apps ?

cc @PVince81 @ChristophWurst @nickvergessen @blizzz @juliushaertl @icewind1991

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.