Webpack clone fails
Bundling & Packing
import a from './a';
import { b } from 'b';
console.log(`a + b = ${a + b}`);
// main.js
const a = _require('./a');
const b = _require('b');
console.log(`a + b = ${a + b}`);
// node_modules/b
const b = 23;
_export = {
..._export,
b
}
// glue code:
function getModule(filepath) {
if (exportsMap[filepath] == null) {
exportsMap[filepath] = {};
moduleMap[filepath](exportsMap[filepath], getModule);
}
return exportsMap[filepath];
}
From
To
import { a } from './a';
import { b } from './b';
import { c } from './c';
setTimeout(() => {
console.log(`main.js | a=${a} | b=${b} | c=${c}`);
});
// in main.js
const a = require("a");
// in a.js
const b = require("b");
// b.js
const a = require("a"); // returns exportsMap[a] = undefined
const c = require("c");
// c.js
const a = require("a"); // returns exportsMap[a] = undefined
const b = require("b"); // returns exportsMap[b] = undefined
exportsMap[c] = "c";
setTimeout(() => {
console.log(`c.js | a=${a} | b=${b}`);
// `c.js | a=undefined | b=undefined`
});
Text
import { a } from './a';
import { b } from './b';
import { c } from './c';
setTimeout(() => {
console.log(`main.js | a=${a} | b=${b} | c=${c}`);
});
// main.js
// The original require
const a = exports("./a").a;
const b = exports("./b").b;
const c = exports("./c").c;
// The hint
setTimeout(() => {
console.log(
`main.js | a=${_require("a")} | b=${_require("b")} | c=${_require("c")}`
);
});
// Results in
[
'main.js | a=a | b=b | c=c',
'a.js | b=b | c=c',
'b.js | a=a | c=c',
'c.js | a=a | b=b',
].join('\n')
// The original require
// const a = exports("./a").a;
// const b = exports("./b").b;
// const c = exports("./c").c;
_require('./a');
_require('./b');
_require('./c');
// The hint
setTimeout(() => {
console.log(
`main.js | a=${_require("a")} | b=${_require("b")} | c=${_require("c")}`
);
});
Why was I insistent in keeping the exports?
Will we still be able to get the console logs according to the direction of traversal of imports?
- No. It is logging in the direction of variables fetched
I don't want to deal with scoping
Loaders
import './style.css';
const div = document.createElement('div');
div.textContent = 'Hello World';
div.className = 'text';
document.body.appendChild(div);
/*
What is folder and main referring to?
*/
module.exports = async function ({ folder, main }, ctx) {
const app = express();
app.use('/index.html', (req, res) => {
res.send(
`<html>
<body>
<script type="module" src="/${path.relative(
folder,
main
)}"></script>
</body>
</html>`
);
});
Where do I insert loaders?
function handleImportDeclaration(path) {
...
path.get("specifiers").forEach((specifier) => {
/**
* Handle file imports. We can extend it to .svg | .jpeg etc.
* import url from './image.png';
*/
if (
t.isImportDefaultSpecifier(specifier) &&
filepath.endsWith(".png") &&
typeof fileLoader === "function"
) {
...
}
// Check file extension and handover to Loaders file
// needs to be processed by loaders
if (filepath.endsWith(".png") && typeof fileLoader === "function") {
// fileLoader(filepath, OUTPUT_DIR);
path.remove();
return;
} else if (filepath.endsWith(".css") && typeof cssLoader === "function") {
filepath = cssLoader(filepath, OUTPUT_DIR);
}
ast = template(`
_require('${getAbsolutePath(filepath)}')
`)();
path.replaceWith(ast);
return;
}
Dev server
Still working on it...
Current failing at
// File watcher
const watcher = require("./watcher");
// TODO: add debounce
watcher(path.dirname(entryFile), (eventType, filename) => {
const modifiedFilepath = path.resolve(path.dirname(entryFile), filename);
const moduleMap = devServerBundle([modifiedFilepath]);
clientSockets().forEach((socket) => {
socket.send(moduleMap); // Should I send a blob?
});
});
// Should this return string?
function devServerBundle(filepaths) {
let moduleMap = "{";
filepaths.forEach((filepath) => {
moduleMap += `"${filepath}": (_exports, _require) => { ${transform(
filepath
)} },`;
});
moduleMap += "}";
return moduleMap;
}
Webpack clone fails
By Chong Jia Wei
Webpack clone fails
- 300