Intro
From ES6, I can import|export JavaScript files as modules on client-side.
But I have used Webpack to bundle files and never tried it.
Because I want to know should I keep using Webpack or importing|exporting modules, I will try it.
Environments
- Node.js ver.16.6.0
- TypeScript ver.4.3.5
- Webpack ver.5.42.0
import|export modules
I can import and export modules as same as using Webpack.
module.page.ts
import * as second from './secondModule';
export function init(): void {
second.addMessage();
}
secondModule.ts
function addMessage(): void {
const target = document.getElementById('message_target') as HTMLElement;
target.textContent = 'Hello World';
}
export { addMessage }
But there are some differences.
For example, this samples only can work on web server.
If I open the HTML file as local files, I will get errors because of CORS restrictions.
I have to add "type="module"" in script tags and when I call exported functions from HTML, I must import the module file.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>module sample</title>
<meta charset="utf-8">
</head>
<body>
<div id="message_target"></div>
<script type="module">
import { init } from './js/module.page.js';
init();
</script>
</body>
</html>
File not found
In this sample, I got one more exception because "secondModule.js" wasn't found.
I used Express and publish JavaScript files as static files.
[Server] index.ts
...
// To receive JSON value from client-side
app.use(express.json());
// To receive Blob value from client-side
app.use(express.raw());
app.use(express.static('clients/public'));
...
I tried importing the file like "import * as second from './secondModule';".
The file path would look like "localhost:3000/js/secondModule", but I really needed to set the path to "localhost:3000/js/secondModule.js".
So I can import the secondModule.js like below.
module.page.ts
import * as second from './secondModule.js';
export function init(): void {
second.addMessage();
}
If I do that, I should research how to add file extensions automatically when I import module files.
Using libraries
How about any libraries like "Moment.js"?
Of cource, it won't be compiled and copied into the output directory.
So I have to copy the files by myself.
Shall I import|export in ES6 way or keep using Webpack?
At least in these samples, I prefer to use Webpack or any other bundling tools.
Because I felt they are more simpler and they can be used in a wider range of environments include IE.
But I'm also interested in import|export of ES6.
Dynamic import
From ES2020, I can also import modules dynamically.
I don't need adding "type="module"" into the script tag.
module.page.ts
// eslint-disable-next-line @typescript-eslint/no-unused-vars
function init(): void {
import('./secondModule.js').then(v => v.addMessage());
}
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>module sample</title>
<meta charset="utf-8">
</head>
<body>
<div id="message_target"></div>
<script src="./js/module.page.js"></script>
<script>init();</script>
</body>
</html>
Dynamic import with Webpack
I can also use dynamic import in the project what is bundled by Webpack.
index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>module sample</title>
<meta charset="utf-8">
</head>
<body>
<div id="message_target"></div>
<script src="./js/module.page.js"></script>
<script>Page.init();</script>
</body>
</html>
module.page.ts
export function init(): void {
import('./secondModule').then(v => v.addMessage());
}
After compiling, "secondModule.js" is separated from the bundled file.
ts_secondModule_ts.js
/*
* ATTENTION: An "eval-source-map" devtool has been used.
* This devtool is neither made for production nor for readable output files.
* It uses "eval()" calls to create a separate source file with attached SourceMaps in the browser devtools.
* If you are trying to read the output file, select a different devtool (https://webpack.js.org/configuration/devtool/)
* or disable the default devtool with "devtool: false".
* If you are looking for production-ready output files, see mode: "production" (https://webpack.js.org/configuration/mode/).
*/
(self["webpackChunkPage"] = self["webpackChunkPage"] || []).push([["ts_secondModule_ts"],{
/***/ "./ts/secondModule.ts":
/*!****************************!*\
!*** ./ts/secondModule.ts ***!
\****************************/
/***/ ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"addMessage\": () => (/* binding */ addMessage)\n/* harmony export */ });\nfunction addMessage() {\r\n const target = document.getElementById('message_target');\r\n target.textContent = 'Hello World';\r\n}\r\n\r\n//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9QYWdlLy4vdHMvc2Vjb25kTW9kdWxlLnRzPzNkZjQiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ3NCIiwiZmlsZSI6Ii4vdHMvc2Vjb25kTW9kdWxlLnRzLmpzIiwic291cmNlc0NvbnRlbnQiOlsiZnVuY3Rpb24gYWRkTWVzc2FnZSgpIHtcclxuICAgIGNvbnN0IHRhcmdldCA9IGRvY3VtZW50LmdldEVsZW1lbnRCeUlkKCdtZXNzYWdlX3RhcmdldCcpO1xyXG4gICAgdGFyZ2V0LnRleHRDb250ZW50ID0gJ0hlbGxvIFdvcmxkJztcclxufVxyXG5leHBvcnQgeyBhZGRNZXNzYWdlIH07XHJcbiJdLCJzb3VyY2VSb290IjoiIn0=\n//# sourceURL=webpack-internal:///./ts/secondModule.ts\n");
/***/ })
}]);
Lazy loading is very useful in some situations.
So I would use it when lazy loading is needed and IE compatibility is not needed :P
Top comments (0)