alexlafroscia / ember-cli-stencil

Automatic discovery of Stencil.js components for your Ember application
26 stars 7 forks source link

Provide a way to pass resourcesUrl to defineCustomElements() #23

Open tomwayson opened 4 years ago

tomwayson commented 4 years ago

We would like to be able to configure the options passed to defineCustomElements(), specifically the resourcesUrl.

It looks like that is called here:

https://github.com/alexlafroscia/ember-cli-stencil/blob/b4bbefdf95863b8e774522b14a1ac0d9295f6e92/packages/ember-cli-stencil/lib/generate-import-initializer.js#L35

I'm guessing that would need to be configurable on a per-library basis.

haoliangyu commented 4 years ago

To resolve this issue, we should be able to provide the import option for custom elements in the build config. Here is a solution:

// ember-cli-build.js

const app = new EmberAddon(defaults, {
  'ember-cli-stencil': {
    // I chose the "collections.name.options" style, but we can discuss
    collections: {
      'custom-elements': {
        importOptions: {
          resourcesUrl: './test/'
        }
      }
    }
  }
});

The options will be passed to the initializer generator function:

// ember-cli-stencil/index.js Line 97

const collectionsConfig = config.collections || {};
const importedCollectionsTree = writeFile(
  'initializers/auto-import-stencil-collections.js',
  // instead of passing an array of collection names, we can pass an array
  // of objects that can contains more values
  generateInitializer(
    this.stencilCollections.map(collection => {
      const config = collectionsConfig[collection.name] || {};
      return {
        name: collection.name,
        // the option can be undefined if not provided 
        importOptions: config.importOptions
      };
    })
  )
);

Then it can pass the options when the define component code are written:

// ember-cli-stencil/lib/generate-import-initializer/js Line 30

const defineComponents = modules.reduce(
  (acc, { polyfillFunction, importFunction, importOptions }) =>
    acc +
    (acc === '' ? '' : '\n') +
    // the options can be directly stringified since it is a simple object
    theredoc`
        ${polyfillFunction}().then(function() {
          ${importFunction}(window, ${JSON.stringify(importOptions)});
        });
      `,
  ''
);

@alexlafroscia @tomwayson I would like to hear your option and I can submit a PR for this.

alexlafroscia commented 4 years ago

I'm not really using Stencil these days, but would love to address this use-case if it's an important one for you!

What @haoliangyu posted looks great to me -- I'm happy for you to open a PR with the code changes (as long as there are some tests, too!)