Last active
November 3, 2020 09:04
-
-
Save dkarmalita/d4664436765d770b889384e6ca37c248 to your computer and use it in GitHub Desktop.
Babel * in-browser setup with only loader from CDN (only index.html and your app.js neccesary)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* You can use require here | |
* @example | |
* const sub = require('./sub') | |
* console.log('SUB >>',sub.default()) | |
*/ | |
ReactDOM.render((<h1>It Works!</h1>), document.getElementById('root')); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
ver: v20201103 | |
url: https://gist.github.com/dkarmalita/d4664436765d770b889384e6ca37c248 | |
cdn: https://gitcdn.xyz/repo/dkarmalita/d4664436765d770b889384e6ca37c248/raw/94ce4b6c7abdd6bf53911437f14850f4d9ad0d04/babel-browser.js | |
*/ | |
function addHeadScript(url, dataset, cb){ | |
const onFinisg = (err) => { if(typeof cb === 'function') cb(err) } | |
const script = document.createElement("script"); | |
script.type="text/javascript" | |
script.onload=(event)=>onFinisg({ event }) | |
script.onerror=()=>onFinisg({ error: new Error(`loading of ${url}`) }) | |
script.src=url | |
script.async=true | |
Object.keys(dataset || {}).forEach(dsk => script.dataset[dsk] = dataset[dsk]) | |
document.getElementsByTagName("head")[0].appendChild(script); | |
} | |
function addHeadScriptsAsync(urls=[], dataset=null){ | |
return Promise.all(urls.map(url => new Promise((resolve, reject) => { | |
addHeadScript(url, dataset, (result) => { | |
if(result.error){ reject(result.error) } | |
resolve(result.event) | |
}) | |
}))) | |
} | |
function babelRegisterPresetPreact(){ | |
Babel.registerPreset("preact", { | |
plugins: [ | |
[Babel.availablePlugins["transform-react-jsx"], { | |
"pragma": "h", | |
"pragmaFrag": "Fragment", | |
}] | |
], | |
}); | |
} | |
function babelTransform(text) { | |
var output = Babel.transform( | |
text, | |
{ | |
presets: [ | |
Babel.availablePresets["env"], | |
Babel.availablePresets["stage-3"], | |
Babel.availablePresets["preact"] || Babel.availablePresets["react"], | |
], | |
} | |
); | |
return output.code | |
} | |
function babelLog(){ | |
console.groupCollapsed(`Babel ${Babel.version}`); | |
console.log('Avaliable presets:', Babel.availablePresets) | |
console.log('Avaliable plugins:', Babel.availablePlugins) | |
console.groupEnd(); | |
} | |
const scripts = [ | |
'https://cdnjs.cloudflare.com/ajax/libs/babel-polyfill/7.12.1/polyfill.min.js', | |
'https://unpkg.com/@babel/standalone/babel.min.js', | |
// 'https://unpkg.com/react@16/umd/react.development.js', | |
// 'https://unpkg.com/react-dom@16/umd/react-dom.development.js', | |
] | |
var dataset = document.currentScript.dataset; | |
addHeadScriptsAsync(scripts) | |
.then((events)=>{ | |
babelLog() | |
if(dataset.preact){ babelRegisterPresetPreact() } | |
window.babelTransform = babelTransform | |
return addHeadScriptsAsync( | |
[ | |
// 'lib/require-polyfill.js', | |
'https://gitcdn.xyz/repo/dkarmalita/d4664436765d770b889384e6ca37c248/raw/4dd3b6c16778b2ce0b887d73f94e8c874ba76b09/require-polyfill.js' | |
], | |
{ | |
projectRoot: './', | |
main: './index.js', | |
...dataset, | |
} | |
) | |
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>Hello!</title> | |
<meta charset="utf-8"> | |
<meta http-equiv="X-UA-Compatible" content="IE=edge"> | |
<meta name="viewport" content="width=device-width, initial-scale=1"> | |
<!-- | |
Load babel & react components and app.js via one babel-browser loader taken from CDN | |
Look at the gist original for more details: | |
https://gist.github.com/dkarmalita/d4664436765d770b889384e6ca37c248 | |
--> | |
<script crossorigin src="https://unpkg.com/react@17/umd/react.development.js"></script> | |
<script crossorigin src="https://unpkg.com/react-dom@17/umd/react-dom.development.js"></script> | |
<script data-project-root="./" data-main="./index.js" src="https://gitcdn.xyz/repo/dkarmalita/d4664436765d770b889384e6ca37c248/raw/94ce4b6c7abdd6bf53911437f14850f4d9ad0d04/babel-browser.js" async></script> | |
</head> | |
<body> | |
<p>Output should appear below.</p> | |
<hr/> | |
<div id="root"></div> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// based on: https://github.com/chenglou/require-polyfill | |
function normalizeArray(parts, allowAboveRoot) { | |
// if the path tries to go above the root, `up` ends up > 0 | |
var up = 0; | |
for (var i = parts.length - 1; i >= 0; i--) { | |
var last = parts[i]; | |
if (last === '.') { | |
parts.splice(i, 1); | |
} else if (last === '..') { | |
parts.splice(i, 1); | |
up++; | |
} else if (up) { | |
parts.splice(i, 1); | |
up--; | |
} | |
} | |
// if the path is allowed to go above the root, restore leading ..s | |
if (allowAboveRoot) { | |
for (; up--; up) { | |
parts.unshift('..'); | |
} | |
} | |
return parts; | |
}; | |
function pathNormalize(path) { | |
var isAbsolute = path.charAt(0) === '/'; | |
var trailingSlash = path.substr(-1) === '/'; | |
// Normalize the path | |
path = normalizeArray(path.split('/').filter(function(p) { | |
return !!p; | |
}), !isAbsolute).join('/'); | |
if (!path && !isAbsolute) { | |
path = '.'; | |
} | |
if (path && trailingSlash) { | |
path += '/'; | |
} | |
return (isAbsolute ? '/' : '') + path; | |
}; | |
var globalEval = eval; | |
var currentScript = document.currentScript; | |
var projectRoot = currentScript.dataset['project-root'] || currentScript.dataset['projectRoot'] || './'; | |
if (projectRoot == null) { | |
throw new Error('The attribute `data-project-root` isn\'t found in the script tag. You need to provide the root (in which node_modules reside).') | |
} | |
var nodeModulesDir = projectRoot + '/node_modules/'; | |
var modulesCache = {}; | |
var packageJsonMainCache = {}; | |
var ensureEndsWithJs = function(path) { | |
if (path.endsWith('.js')) { | |
return path; | |
} else { | |
return path + '.js'; | |
} | |
}; | |
function loadScript(scriptPath) { | |
var request = new XMLHttpRequest(); | |
request.open("GET", scriptPath, false); // sync | |
request.send(); | |
if(request.status !== 200){ return } | |
var dirSeparatorIndex = scriptPath.lastIndexOf('/'); | |
var dir = dirSeparatorIndex === -1 ? '.' : scriptPath.slice(0, dirSeparatorIndex); | |
var transpiledText = window.babelTransform ? babelTransform(request.responseText) : request.responseText; | |
var moduleText = ` | |
(function(module, exports, modulesCache, packageJsonMainCache, nodeModulesDir) { | |
function require(path) { | |
var __dirname = "${dir}/"; | |
var resolvedPath; | |
if (path.startsWith('.')) { | |
// require('./foo/bar') | |
resolvedPath = ensureEndsWithJs(__dirname + path); | |
} else if (path.indexOf('/') === -1) { | |
// require('react') | |
var packageJson = pathNormalize(nodeModulesDir + path + '/package.json'); | |
if (packageJsonMainCache[packageJson] == null) { | |
var jsonRequest = new XMLHttpRequest(); | |
jsonRequest.open("GET", packageJson, false); | |
jsonRequest.send(); | |
var main; | |
if (jsonRequest.responseText != null) { | |
main = JSON.parse(jsonRequest.responseText).main; | |
}; | |
if (main == null) { | |
main = 'index.js'; | |
} else if (!main.endsWith('.js')) { | |
main = main + '.js'; | |
} | |
packageJsonMainCache[packageJson] = nodeModulesDir + path + '/' + main; | |
} | |
resolvedPath = packageJsonMainCache[packageJson]; | |
} else { | |
// require('react/bar') | |
resolvedPath = ensureEndsWithJs(nodeModulesDir + path); | |
}; | |
resolvedPath = pathNormalize(resolvedPath); | |
if (modulesCache[resolvedPath] != null) { | |
return modulesCache[resolvedPath]; | |
}; | |
// initialize cache with an empty object, allows circular dependencies | |
modulesCache[resolvedPath] = {}; | |
var result = loadScript(resolvedPath); | |
modulesCache[resolvedPath] = result; | |
return result; | |
}; | |
var process = {env: {}, argv: []}; | |
var global = {}; | |
// -------Begin Require Polyfilled Module Loaded From Disk------------------------------ | |
// file: ${scriptPath} | |
// root: ${projectRoot} | |
// ---------------------------------------------------------------------- | |
${transpiledText} | |
// -------End Polyfill Loaded From Disk------------------------------ | |
// file: ${scriptPath} | |
// root: ${projectRoot} | |
// ---------------------------------------------------------------------- | |
return module.exports})\n//@ sourceURL=${scriptPath}`; | |
var module = {exports: {}}; | |
return globalEval( moduleText )(module, module.exports, modulesCache, packageJsonMainCache, nodeModulesDir); | |
}; | |
loadScript(currentScript.dataset.main || './index.js') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment