hexojs / hexo

A fast, simple & powerful blog framework, powered by Node.js.
https://hexo.io
MIT License
38.83k stars 4.75k forks source link

site.categories.data is not iterable #5367

Closed D-Sketon closed 2 months ago

D-Sketon commented 7 months ago

Check List

Expected behavior

are iterable before v7

Actual behavior

https://github.com/orgs/hexojs/discussions/5355 hexo.locals.get('categories') before PR:

_Query {
  data: [
    _Document {
      name: 'test1',
      _id: 'clph3uowl0001y0vr98rqaoln',
      slug: [Getter],
      path: [Getter],
      permalink: [Getter],
      posts: [Getter],
      length: [Getter]
    }
  ],
  length: 1
}

after PR:

_Model {
  _events: [Object: null prototype] {},
  _eventsCount: 0,
  _maxListeners: undefined,
  name: 'Category',
  _mutex: Mutex { _locked: false, _queue: [] },
  data: {
    clph3uy05000130vr2iwbbjgi: { name: 'test1', _id: 'clph3uy05000130vr2iwbbjgi' }
  },
  length: 1,
  schema: Schema {
    paths: {
      name: [SchemaTypeString],
      parent: [SchemaTypeCUID],
      slug: [SchemaTypeVirtual],
      path: [SchemaTypeVirtual],
      permalink: [SchemaTypeVirtual],
      posts: [SchemaTypeVirtual],
      length: [SchemaTypeVirtual],
      _id: [SchemaTypeCUID]
    },
    statics: {},
    methods: {},
    hooks: { pre: [Object], post: [Object] },
    stacks: {
      getter: [Array],
      setter: [Array],
      import: [Array],
      export: [Array]
    }
  },
  Document: [class _Document extends Document],
  Query: [class _Query extends Query],
  [Symbol(kCapture)]: false
}

How to reproduce?

just use v7 related PR: https://github.com/hexojs/hexo/pull/5119 This may affect some of the Hexo themes

Is the problem still there under Safe mode?

/

Your Node.js & npm version

No response

Your Hexo and Plugin version

No response

Your package.json

No response

Your site's _config.yml (Optional)

No response

Others

related code

https://github.com/hexojs/hexo/blob/f5e0f92eda9491116c585142c565efcf7bf7a3e3/lib/hexo/index.ts#L297-L299

yoshinorin commented 7 months ago

IMHO, If we can't fix it, we should revert #5119 and release a patch version v7.0.1.

D-Sketon commented 7 months ago

cc @stevenjoezhang

yoshinorin commented 7 months ago

IMHO, If we can't fix it, we should revert https://github.com/hexojs/hexo/pull/5119 and release a patch version v7.0.1.

IMHO, categories.data should be Iterable, but it could also be considered as a Breaking Change in v7.0.0. Because it can be avoided in the following way (although there might be a slight performance impact caused by Object.values).

Workaround

const Hexo = require('hexo');
const hexo = new Hexo(process.cwd(), {silent: false});

hexo.init().then(() => {
  hexo.load().then(() => {
    const categories = hexo.locals.get('categories')

    for(const category of Object.values(categories.data)) {
      console.log(category)
    }
  })
}
// result
...
{
  name: 'AWS SQS',
  parent: 'clpi63on909jhecue8bzt7o3a',
  _id: 'clpi63q3b09yaecue1ktx3y1z'
}
{
  name: 'webpack',
  parent: 'clpi63oq709muecue55jv5g3w',
  _id: 'clpi63q3e09yhecue3qui5w17'
}
{
  name: 'AWS EC2',
  parent: 'clpi63on909jhecue8bzt7o3a',
  _id: 'clpi63q3h09ykecue10blf69w'
}
{
  name: 'AWS RDS',
  parent: 'clpi63on909jhecue8bzt7o3a',
  _id: 'clpi63q3j09ynecuehqre75xl'
}
{
  name: 'Node.js',
  parent: 'clpi63opr09mbecueakys6msw',
  _id: 'clpi63q3k09yqecue4f5542hx'
}
{
  name: 'AWS CDK',
  parent: 'clpi63on909jhecue8bzt7o3a',
  _id: 'clpi63q3m09yuecueg0dua4iy'
}
{
  name: 'Scala',
  parent: 'clpi63oww09qaecue6f4o069e',
  _id: 'clpi63q3q09z0ecuehx9n6tth'
}
...
saicaca commented 7 months ago

Besides the problem mentioned I have another question that may be relevant.

Before v7 the number of articles under each category can be retrieved using categories.data[i].length. In v7 the property length no longer exists (along with some other properties). Is this an intentional change? If so, is there an alternative method to access it?

D-Sketon commented 7 months ago

Besides the problem mentioned I have another question that may be relevant.

Before v7 the number of articles under each category can be retrieved using categories.data[i].length. In v7 the attribute length no longer exists. Is this an intentional change? If so, is there an alternative method to access it?

No, it's not an intentional change, this is a side effect of optimization

D-Sketon commented 7 months ago

Even through Object.values there is no access to the length field that was there, so is this breaking change acceptable?

stevenjoezhang commented 7 months ago

This issue is quite tricky. Hexo provides a well-encapsulated warehouse Query object, but indeed, many themes make use of the private data attribute.

uiolee commented 6 months ago

you can use toArray() or forEach()

toArray()

    const array = hexo.locals.get("tags").toArray();
    for (item of array) {
        console.log(item.name, item.length);
    }

forEach()

    hexo.locals.get("tags").forEach((item) => {
        console.log(item.name, item.length);
    });

https://hexojs.github.io/warehouse/classes/model.default.html#toArray https://hexojs.github.io/warehouse/classes/model.default.html#forEach