从ember插件中的node_modules导入scss

vwhgwdsa  于 2022-09-28  发布在  其他
关注(0)|答案(1)|浏览(212)

我正在开发一个ember插件,它从其依赖项导入sass。为了使用它,我的插件中有以下内容-


# my-addon/package.json

...
"dependencies": {
  "lib1": "^1.5.3",
  "lib2": "1.2.3",
  "ember-cli-sass": "^10.0.1",
  "sass": "^1.23.3"
}
...

b1a1a


# my-addon/ember-cli-build.js

let app = new EmberAddon(defaults, {
  // Add options here
  sassOptions: {
    includePaths: [
      'node_modules'
    ]
  }
});

这样,tests/dummy处的虚拟应用程序可以解析导入。但当我在主机应用程序中使用插件时

Error: Can't find stylesheet to import.
  ╷
1 │ @import "lib1/assets/stylesheets/styles";
  │         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

我可以将主机应用的e1d1e修改为

let app = new EmberAddon(defaults, {
  // Add options here
  sassOptions: {
    includePaths: [
      'node_modules/my-addon/node_modules'
    ]
  }
});

理想情况下,它应该可以工作,但sass内存不足,因为它试图导入主机应用程序node_modules中的所有内容。如何使虚拟应用程序和主机应用程序都能够导入命名空间lib-scs?

ui7jx7zq

ui7jx7zq1#

写我的插件我也有同样的问题!
我做了大量的研究,把学到的东西混合起来,得出了以下结论。

描述场景:

编写一个EmberJS Addon来提供材质设计组件,在本地安装库,并且只针对我想要插件的组件和行为,重用并作为自定义成员组件公开。类似于采用的插件Ember paper

  • 嵌入版本和@material依赖项*
// my-addon/package.json
  ...
  "ember-source": "~4.5.0",
  "@material/theme": "^14.0.0",
  "@material/typography": "^14.0.0",
  "ember-cli-sass": "^11.0.1",
  "sass": "^1.53.0",
  ...
  "ember": {
    "edition": "octane"
  },
  ...

注意,对于这个答案,我只添加了@material/typography

// my-addon/app/styles/my-addon.scss
  @use "@material/typography" with (
    // Customize material font-family
    $font-family: unquote("Any-font-you-want, sans-serif")
  );
  // Import material typography styles
  @use "@material/typography/mdc-typography";

我第一次犯了同样的错误->将sassOptions添加到ember-cli build。jsincluding the wholenode_modulespath. But the comment that the addon-cli wrote in theember-clibuild文件让我意识到我错了。 /*此构建文件指定此插件的虚拟测试应用程序的选项,位于/tests/dummy中。此构建文件*不*影响插件或使用它的应用程序的行为。您很可能希望修改./index.js`或应用程序的构建文件*/

解决方案

首先,我们应该安装一些npm包

"resolve": "^1.22.1",
"broccoli-funnel": "^3.0.8",
"broccoli-merge-trees": "^4.2.0",

resolve
异步将模块路径字符串id解析为cb(err,res[,pkg]),其中pkg(如果已定义)是package.json中的数据
broccoli-funnel
给定一个输入节点,Brocoli漏斗插件返回一个新节点,其中只包含输入节点中文件的子集。文件可以移动到不同的路径。可以使用正则表达式选择要包含或排除的文件。
broccoli-merge-trees
将文件的多个树相互重叠复制,从而形成一个合并树。

// my-addon/index.js

  // Import packages to work with trees and paths
  const path = require('path');
  const resolve = require('resolve/sync');
  const funnel = require('broccoli-funnel');
  const { MergeTrees } = require('broccoli-merge-trees');

  /*
   Below you can see an array of objects representing the
   material path and the component name. Notice that we only
   installed the @material/typography but the component uses other
   material dependencies internally.

   We will merge all `scss` and `sass` files from those paths
   to allow us imports the @material/typography at
   #my-addon/app/styles/my-addon.scss.

   Following this design, if you forget to include some path
   you will receive errors saying which paths are missing. 
  */

  const materialPackages = [
    { name: 'theme', path: '@material/' },
    { name: 'typography', path: '@material/' },
    { name: 'feature-targeting', path: '@material/' },
  ];

module.exports = {
  name: require('./package').name,

  included: function (/* app */) {
    this._super.included.apply(this, arguments);
  },

  treeForStyles(tree) {
    let trees = [];

    let pathBase;
    materialPackages.forEach(function (pkg) {
      pathBase = path.dirname(
        resolve(`${pkg.path}/${pkg.name}/package.json`, {
          basedir: __dirname,
        })
      );

      trees.push(
        // Using broccoli to return a new tree with the
        // files that matches the include property rules.
        // import: ['**/*.{scss,sass}']
        funnel(pathBase, {
          destDir: `${pkg.path}/${pkg.name}`,
          include: ['**/*.{scss,sass}'],
        })
      );
    });

    // Push existing tree
    tree && trees.push(tree);

    // Returninng merged broccoli tress
    return new MergeTrees(trees, { overwrite: true });
  }
}

这样,您就可以在虚拟应用程序或其他使用npm链接或发布插件的应用程序中使用插件及其外部sass文件。
请注意,我倾向于强制插件消费者导入@import 'my-addon-scss';。我没有直接在#my-addon/addon/styles/addon.scss上测试提供样式。
我相信这个答案可以引发关于创建ember附加组件的讨论。
我希望我能得到答案,使我的代码更好。

参考文献

相关问题