LongTengDao / j-toml

A Node.js implementation of TOML written by LongTengDao. Belong to "Plan J"./龙腾道为汤小明语写的 Node.js 实现。从属于“简计划”。
https://npmjs.com/package/@ltd/j-toml
GNU Lesser General Public License v3.0
55 stars 6 forks source link

What does `.Error` mean in `import Error from '.Error'`? #3

Closed ilyaigpetrov closed 3 years ago

ilyaigpetrov commented 3 years ago

Hello. I've never seen such import declaration: import Error from '.Error';. Why does it start with a dot? What behavior should I expect from this notation? Please, share a link to some article about this declaration.

Thank you, Ilya.

LongTengDao commented 3 years ago

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/dist/ESM/.j-toml.js#L12

It seems you are using dist/ESM/.j-toml.js for packing, which is a middle packed edition for further packing. Module '.Error' just means global variable Error itself, without any other magic. Dot module won't appear in final dist runtime code.

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/dist/ESM/j-toml.js#L14

dist/ESM/j-toml.js edition (without start dot in filename) is the format that people usually use to pack for the time being, you can use that for simplicity.

It's also possible that you are reading the source.

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/src/parse/.ts#L1

Just remeber, module id starting with a dot means that's a global variable in most cases; and if it does not exist in js spec, it's my personal util (only very small and very common use util that not worth to be independent package to publish, like '.throw.TypeError', which means function throwTypeError (msg) { throw TypeError(msg); }, which allow throw error in expression input.match(REG_EXP) || throwTypeError('...') e.g.).


.j-toml.js tool support is currently not published for public, but I can explain ahead.

For example, Object.prototype.hasOwnProperty is slow and mutable and can not be minified, so I write const hasOwnProperty = Object.prototype.hasOwnProperty instead in almost all project.

But that has a problem, if my downstream project packed a lot of upstream packages, then here will be a lot of repeating of same thing. So in .j-toml.js edition, I remained all reference as import hasOwnProperty from '.Object.prototype.hasOwnProperty'; style. Module ID starts with . means that's a global variable.

'.Error' is the same. That also helps for avoiding accidental global variables reference (I do not allow any bare global reference in my project), and make it easy to use or remove polyfill (like '.Reflect.apply' means directly use, '.Reflect.apply?' means typeof Reflect==='undefined' ? undefined : Reflect.apply, '.Reflect.apply?=customPolyfillExpression' means typeof Reflect==='undefined' ? customPolyfillExpression : Reflect.apply, and '.Reflect.apply?=' means default polyfill; and the polyfill part will be skipped if same project reference same feature without polyfill syntax).

Welcome to discuss.

ilyaigpetrov commented 3 years ago

.j-toml.js tool support is currently not published for public[...]

So I can't reproduce the build and verify the dist package. Without verification the usage of your code is risky. Also I would like to work with some popular module bundler (rollup, webpack) because this way it will be easier to verify your code.

Not that I verify every npm package with sources, I almost never do it, but I feel more trust to packages that can be verified by a community.

LongTengDao commented 3 years ago

Of cause! That's necessary.

In fact the bundler tool I use is a custom edition rollup (approximate rollup + dot module plugin + terser).

I just have too many package in publishing process, including bundler tool. People won't accept what you worried, me too.

Thank you for communication!

LongTengDao commented 3 years ago

I found a temporary way to confirm the dist safe, by easily search in the dist file:

  1. The dist code only includes one require('fs').readFileSync in the parse, which only called for sourcePath parameter
  2. parse is not called in the dist code self
  3. There is no any more require or import called
  4. There is no net API called
  5. There is no eval reference, no Function reference, and only two constructor property access which only lead to delete behaviour, which won't reference Function indirectly.

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/dist/NPM/index.js#L1939

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/dist/NPM/index.js#L384

https://github.com/LongTengDao/j-toml/blob/ebcd61c6910d1527d2f1b7d503a3d18089a6ff96/dist/NPM/index.js#L494

@ilyaigpetrov Hope this would help.

ilyaigpetrov commented 3 years ago

If some other developer can't fork your project and develop/build it himself with the same provided toolset (for the equal productivity) as you then I doubt it should be called "Open Source". For the same reason we don't call obfuscated sources "Open Source" because editing obfuscated code can't compete in productivity with editing original code. I'm not a guru of open source philosophy, I can mistake, but that's how I get it.

I guess, "being open to competition" -- that's how it may be called.

LongTengDao commented 3 years ago

Since 1.17.0, @ltd/j-toml removed internal require('fs') for TOML.parse({ path }), so the temporary way to confirm the dist safety is easier now:

  1. There is no any import or require [^1] reference
  2. There is no any net API reference
  3. There is no any native API override
  4. There is no any eval reference, also no Function reference, and only two constructor property access which only lead to delete input.prototype.constructor behaviour for library data, which won't reference Function indirectly

[^1]: Remain one place in TOML.parse for users before 1.17.0 lacking options.require compatibility.