Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

🙋: Ignore certain code sections #357

Open
agauniyal opened this issue Dec 20, 2017 · 9 comments
Open

🙋: Ignore certain code sections #357

agauniyal opened this issue Dec 20, 2017 · 9 comments

Comments

@agauniyal
Copy link

🙋

Sometimes there are code portions that I don't want parcel to parse and completely ignore them while acting normally on rest of the file. An example is embedding monaco-editor where index.html code looks like -

<!DOCTYPE html>
<html>
<head>
	<meta http-equiv="X-UA-Compatible" content="IE=edge" />
	<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
</head>
<body>

<div id="container" style="width:800px;height:600px;border:1px solid grey"></div>

<!-- I want this section to be ignored by parcel -->
<script src="monaco-editor/min/vs/loader.js"></script>
<script>
	require.config({ paths: { 'vs': 'monaco-editor/min/vs' }});
	require(['vs/editor/editor.main'], function() {
		var editor = monaco.editor.create(document.getElementById('container'), {
			value: [
				'function x() {',
				'\tconsole.log("Hello world!");',
				'}'
			].join('\n'),
			language: 'javascript'
		});
	});
</script>
<!-- Section End -->

<!-- This should work normally -->
<script src="./index.js"></script>

</body>
</html>

🤔 Expected Behavior

Parcel should be able to ignore certain sections.

😯 Current Behavior

It'll try parsing the file but would not do it the right way so browser errors out. This is because monaco-editor has a long standing issue here - microsoft/monaco-editor#18 and I manually copy node_modules/monaco-editor to public directory in my build step.

💁 Possible Solution

Use comments to inform parcel.js to ignore these sections(like eslint does)..

🔦 Context

Showstopper for me because I can't migrate to parcel.

🌍 Your Environment

Software Version(s)
Parcel 1.2.1
Node 9.3.0
npm/Yarn 1.3.2
Operating System Arch Linux
@rondonjon
Copy link

Sounds very much like an edge-case to me. You could achieve the same with a custom preprocessor.

@shawwn
Copy link
Contributor

shawwn commented Dec 21, 2017

During html parsing, we could skip nodes that set the attribute data-parcel="false".

That would be a decent design choice because we could extend it to data-parcel="process.env.NODE_ENV === 'production'" if necessary.

@jdanyow
Copy link
Contributor

jdanyow commented Dec 24, 2017

@agauniyal here's a workaround for monaco (using cdn). Not pretty but gets around the conflict between the monaco loader's require and parcel's require.

const cdnBase = 'https://cdnjs.cloudflare.com/ajax/libs/monaco-editor/0.10.1/min';

fetch(`${cdnBase}/vs/loader.js`, { mode: 'cors' })
  .then(response => response.text())
  .then(text => {
    const monacoLoader = {} as any;
    window.monacoLoader = monacoLoader;
    text = text
      .replace(/var\s+_amdLoaderGlobal\s*=\s*this/, 'var _amdLoaderGlobal = window.monacoLoader')
      .replace(/this\.isNode\s*=\s*e\.isNode/, 'this.isNode = false');
    eval(text);
    monacoLoader.require.config({ paths: { 'vs': `${cdnBase}/vs` } });
    window.define = monacoLoader.define;
    window.MonacoEnvironment = {
      getWorkerUrl: () => URL.createObjectURL(new Blob([loaderProxyScript], { type: 'application/javascript' }))
    };
    monacoLoader.require(['vs/editor/editor.main'], () => {
      const editor = monaco.editor.create(document.getElementById('container')!, {
        value: [
          'function x() {',
          '\tconsole.log("Hello world!");',
          '}'
        ].join('\n'),
        language: 'javascript'
      });
    });
  });

interface Window {
  define: any;
  monacoLoader: {
    define: any;
    require: any;
  },
  MonacoEnvironment: any;
}

const loaderProxyScript = `self.MonacoEnvironment = {
    baseUrl: '${cdnBase}'
};
importScripts('${cdnBase}/vs/base/worker/workerMain.js');`

@danmarshall
Copy link
Contributor

@agauniyal I had the same problem, I'm also trying to use Monaco. Coincidentally, today they just fixed microsoft/monaco-editor#18 👍
However, Monaco workers also need to be bundled. Monaco is loading worker bundles by URL. @alexandrudima has provided examples 👍 how to do this with Webpack, but I have yet to figure out how to get these to work with Parcel.

@nvenegas
Copy link

nvenegas commented Apr 5, 2018

I think I'm running into the same issue:

I want to output an <iframe> with the srcdoc attribute being the contents of a (local to the package) file that would otherwise have been referenced via the src attribute directly.

I end up with a compiled file where srcdoc contains a reference to a script:

<script type="text/javascript" src="./one.js"></script>

and parcel's resolution of the "./one.js" inside the srcdoc attribute fails.

The behaviour I want is for parcel to not reach into srcdoc at all.

@fathyb
Copy link
Contributor

fathyb commented Apr 5, 2018

Monaco-Editor now supports Parcel, even with workers. See microsoft/vscode#46032 and microsoft/monaco-editor#774

@danmarshall
Copy link
Contributor

@fathyb would you mind taking a look at my sample in https://github.com/Microsoft/monaco-editor-samples/blob/master/browser-esm-parcel/index.html - and letting me know if there is a better way to build and refer to the worker?

@fathyb
Copy link
Contributor

fathyb commented Apr 7, 2018

@danmarshall it doesn't look like it's been released to npm yet. Any idea when the next release is?

Once it gets released you could do (without the build node_modules/monaco-editor/esm/vs/editor/editor.worker.js command) :

self.MonacoEnvironment = {
	getWorker: function (moduleId, label) {
            return new Worker('./node_modules/monaco-editor/esm/vs/editor/editor.worker')
        }
}

You can try it by applying the PR manually by overwriting node_modules/monaco-editor/esm/vs/base/worker/defaultWorkerFactory.js beginning to this :

import { globals } from '../common/platform.js';
import { logOnceWebWorkerWarning } from '../common/worker/simpleWorker.js';
function getWorker(workerId, label) {
        // Option for hosts to overwrite the worker script (used in the standalone editor)
        if (globals.MonacoEnvironment) {
                if (typeof globals.MonacoEnvironment.getWorker === 'function') {
                        return globals.MonacoEnvironment.getWorker(workerId, label);
                }
                if (typeof globals.MonacoEnvironment.getWorkerUrl === 'function') {
                        return new Worker(globals.MonacoEnvironment.getWorkerUrl(workerId, label));
                }
        }
        throw new Error(`You must define a function MonacoEnvironment.getWorkerUrl or MonacoEnvironment.getWorker`);
}
var WebWorker = /** @class */ (function () {
    function WebWorker(moduleId, id, label, onMessageCallback, onErrorCallback) {
        this.id = id;
        this.worker = getWorker('workerMain.js', label);

new Worker('monaco-editor/esm/vs/editor/editor.worker') doesn't work while new Worker('./node_modules/monaco-editor/esm/vs/editor/editor.worker') works, not sure if it's intended or a bug. It yields this : (cc @devongovett)

🚨  /~/browser-esm-parcel/index.js:107:20:
Cannot resolve dependency './monaco-editor/esm/vs/editor/editor.worker'
at '/~/browser-esm-parcel/monaco-editor/esm/vs/editor/editor.worker'

@danielo515
Copy link

I am also interested on this functionality.
In my case I want to leave some sections of the html file with template sections that I will then render on the server. The proposed approach seems fine to me, or even better using the data attributes of the tags.
This is not an edge case at all, I think it is a nice yet simple feature that could open a world of possibilities.

Regards

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

9 participants