Code Splitting in Angular/Formly to avoid building the whole project for small changes

100 Views Asked by At

I'm building a webapp that requires an ever-growing collection of forms. Formly seems to be an excellent tool to do this because it's declarative and reusable. However, placing formly field config files in the same project, even on a separate module, means that for every new form or every small changes to the form, the project has to be build and deployed again, or at least that's what I've been doing so far.

An ideal solution would have these conditions:

  1. Code separation between the main webapp and the forms, so it can be managed separately. Currently I have separated the forms (configs, components, and custom fields) into a separate angular module, in the same project.
  2. As close to zero downtime as possible. Updating forms or adding new forms should be very easy and quick. JSON/JSON Schema powered forms might be plausible with some limitations. I've experimented a bit with transpiling and dynamically importing .ts form files with no luck so far.
  3. Reusable and Nest-able. It's great to have let say an Address form (which includes address, postal code, city, state/province, etc), so whenever I need a full Address form I can just call and insert into a fieldGroup somewhere.

Possible solutions that I've tried:

  1. Create a separate server/service that generate a full form FormlyFieldConfig object based on multiple nested forms, for example a User form would have username, password, Person fields containing personal information, and Address fields like in condition 3 above. The problem with this approach is that sending functions (such as onInit in hooks) as a string through http response doesn't seem like a good idea.
  2. Storing forms in JSON/JSON Schema. There's 2 problems with this approach. First, I'm not sure how to nest forms from multiple .json files. Second, it's not even possible to store functions in JSON so I have to rely entirely on formly's expression.
  3. Sending/requesting form .ts files on demand, transpiling and running them when needed. I've researched and tried eval() and import(). It works when the form files is in the same project, which doesn't satisfy the 2nd condition, so importing files (modules) from remote location doesn't seem to be possible.
  4. Separating the forms to a separate library. But, when I update the library, I'd have to do npm install and npm build on the project, unless I'm missing something.

Question: Is there a better way of doing this? Or do I miss/misunderstood something? Is it possible to do lazy loading, but the module is on for example a CDN?

EDIT:

I found out how to convert functions to string and vice versa

export const getCircularReplacer = () => {
  const seen = new WeakSet();
  return (key, value) => {
    
    if (typeof value === "object" && value !== null) {
      if (seen.has(value)) {
        return;
      }
      seen.add(value);
    }
    if(typeof value === "function") {
      return value.toString();
    }
    return value;
  };
};

then,

JSON.stringify(formlyFieldConfigs, getCircularReplacer())

and to convert back to object

export const getReviver = (_this, ...params) => {
  return (key, value) => {
    if(key == "hooks") {
      let hooks = {};
      Object.keys(value).forEach(hookKey => {
        hooks[hookKey] = eval(value[hookKey]);
      });
      return hooks;
    }
    if(value.templateOptions != null) {
      if(value.templateOptions.optionsFunctionName) {
        let functionName = value.templateOptions.optionsFunctionName;
        value.templateOptions.options = _this[functionName](params);
      }
    }
    return value;
  }
};

basically it's using eval() and this.[functionName](params) pattern, then call,

JSON.parse(string, getReviver(this))

But sending functions over string still doesn't seem like the right approach.

0

There are 0 best solutions below