afterwind-io / preprocessor-loader

Bring the awesome "Conditional Compilation" to the Webpack, and more.
MIT License
40 stars 12 forks source link

The if directive implementation may cause wrong result #13

Closed scarletsky closed 3 years ago

scarletsky commented 3 years ago

Currently the if directive is implemented by the following function:

export function ifComparator(params: IParamsMap, rawCondition: string): boolean {
    const keys = Object.keys(params);
    const values = keys.reduce((v, key) => v.concat(params[key]), []);
    const comparator = new Function(...keys, `return ${rawCondition};`);
    return comparator(...values);
}

v.concat may cause wrong result if the value type is Array. Just a little snippet:

const testObj = { a: 1, b: [0, 2, 3] };
const keys = Object.keys(testObj);
const values = keys.reduce((v, key) => v.concat(testObj[key]), []);

keys is ["a", "b"] values is [1, 0, 2, 3] (new Function(...keys, 'return b;'))(...values) will return 0, and this is an unexpected result.

A more robust way is to use push instead of concat.

afterwind-io commented 3 years ago

@scarletsky 这个情况倒是的确没想到...

数组的问题已经修复了,补丁对应版本为1.1.4。

关于这个concat的问题,其实直接用map就行了: https://github.com/afterwind-io/preprocessor-loader/blob/40b3e132daf4c17b8dd4d932c08ffef5346ed120/src/filter.ts#L109

scarletsky commented 3 years ago

@afterwind-io 哈哈,map 也可以。我也是刚好碰到打包出现异常的时候才留意到这个问题。