JavaやPHPなどのプログラミング言語の名前付けに非常に感銘を受けました。どういうわけかHabréにそれらについての記事を書いたほどです。それからほぼ2年が経過しましたが、この間、名前名はJavaScriptに表示されていません。「そして、もし私が自分のためにJSで名前付けをしたとしたら、それらは何でしょうか?」-私は思った。カットの下で-私の考え、JavaScriptで必要な名前名。
入門
以下の私の推論はすべてES6モジュールに適用され、 JavaScriptがどこにあるのかではなく、どこに行くのかを監視することに関心があるという理由だけで、他の形式(AMD、UMD、CommonJS)には触れません。また、私の練習では、どういうわけかGWTに非常に密接に遭遇し、その後、さまざまなトランスパイラー(およびヒープ、ミニファイア、オブファキュレータ)の永続的な拒否を開発しました。したがって、バニラJSでTSはありません。さて、そういうものがあります。
ES6モジュール
ESモジュールは、モジュールの外部で使用可能な要素を明示的に定義する別個のソースファイルです。
export function fn() {/*...*/}したがって、最初に、アプリケーション全体内の個々のESモジュールに何らかの方法で対処する必要があります。
パッケージ
, . . (vendor) , . (, ./src).
node_modules. , nodejs-, , :
* node_modules
* @vendor
* package1
* src
* module1.js
* ...
* moduleN.js
* ...
* packageN
* src
* module1.mjs
* ...
* moduleN.mjsES- :
./node_modules/@vendor/package1/src/module1.js
...
./node_modules/@vendor/packageN/src/moduleN.mjs nodejs- ./node_modules/ :
import SomeThing from '@vendor/package1/src/module1.js';, , :
import SomeThing from './module1.js'; web- , web- node_modules, web- ES-, , nodejs:
<script type="module">
import {fn} from './@vendor/package1/src/module1.js'
fn();
</script>:
<script>
import('./@vendor/package1/src/module1.js').then((mod) => {
mod.fn();
});
</script> , web' ./ . :
import {fn} from '@vendor/package1/src/module1.js':
Uncaught TypeError: Failed to resolve module specifier "@vendor/package1/src/module1.js". Relative references must start with either "/", "./", or "../".
, ES-:
( ):
./module1.js(nodejs):
@vendor/package1/src/module1.js(web):
./@vendor/package1/src/module1.js
./ nodejs-, ./ .
, JS- , , ( - ) , ( ).
" " ( , namespace'), ES- ( ), ES- , , nodejs, .
, ./, , ( , ):
@vendor/package1/src/module1 - : ./src/, ./lib/, ./dist/. - , , :
@vendor/package1/module1, , .
Namespace mapping
, , . - web-, node_modules web- ( - ./packages/):
const node = {
'@vendor/package1': {path: '/.../node_modules/@vendor/package1/src', ext: 'js'},
'@vendor/packageN': {path: '/.../node_modules/@vendor/packageN/src', ext: 'mjs'},
};
const browser = {
'@vendor/package1': {path: 'https://.../packages/@vendor/package1/src', ext: 'js'},
'@vendor/packageN': {path: 'https://.../packages/@vendor/packageN/src', ext: 'mjs'},
};Module loader
, '' ( @vendor/package1/module1) ( - ) (node ):
@vendor/package1/module1 => /.../node_modules/@vendor/package1/src/module1.js // node
@vendor/packageN/moduleN => https://.../packages/@vendor/packageN/src/moduleN.mjs // browserモジュールを動的にインポートするために使用します。もちろん、パッケージ内のすべてのモジュールをマップする必要はありません。パッケージのルートをマップするだけです。出力は次のようになります。
const loader = new ModuleLoader();
loader.addNamespace('@vendor/package1', {path: '/.../node_modules/@vendor/package1/src', ext: 'js'});
// ...
loader.addNamespace('@vendor/packageN', {path: '/.../node_modules/@vendor/packageN/src', ext: 'js'});
const module1 = await loader.import('@vendor/package1/module1');モジュールのインポートは非同期である必要があります。非同期関数が内部で使用されimport()ます。
概要
このような洗練された方法で、インポート中のESモジュールの物理アドレス指定から論理アドレス指定(名前空間)に移動し、nodejsアプリケーションとブラウザーの両方で同じモジュールを使用することができます。ここでは新しいものは何も発明されていません(このアイデアが盗まれたところから、PHPでも同様のことがすでに行われています)。