fix(client): prevent endless SASS conversion
This commit is contained in:
parent
39e936bbaa
commit
ecadba95db
5
client/.gitignore
vendored
5
client/.gitignore
vendored
@ -9,6 +9,5 @@ config/env.json
|
||||
/public
|
||||
.DS_Store
|
||||
|
||||
./static/js/frame-runner.js
|
||||
./static/js/frame-runner.js.map
|
||||
./static/_redirects
|
||||
/static/js
|
||||
./static/_redirects
|
||||
|
11
client/src/client/workers/sass.js
Normal file
11
client/src/client/workers/sass.js
Normal file
@ -0,0 +1,11 @@
|
||||
/* eslint-disable */
|
||||
importScripts(
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.11/sass.sync.min.js'
|
||||
);
|
||||
|
||||
onmessage = e => {
|
||||
const data = e.data;
|
||||
Sass.compile(data, result => {
|
||||
self.postMessage(result.text);
|
||||
});
|
||||
}
|
@ -1,11 +1,10 @@
|
||||
import favicons from './favicons';
|
||||
import meta from './meta';
|
||||
import mathjax from './mathjax';
|
||||
import sassjs from './sassjs';
|
||||
import scripts from './scripts';
|
||||
|
||||
const metaAndStyleSheets = meta
|
||||
.concat(favicons, mathjax, sassjs, scripts)
|
||||
.concat(favicons, mathjax, scripts)
|
||||
.map((element, i) => ({
|
||||
...element,
|
||||
key: `meta-stylesheet-${i}`,
|
||||
|
@ -1,8 +0,0 @@
|
||||
import React from 'react';
|
||||
|
||||
const cdnAddr =
|
||||
'https://cdnjs.cloudflare.com/ajax/libs/sass.js/0.10.9/sass.sync.min.js';
|
||||
|
||||
const sassjs = [<script key='sassjs' src={cdnAddr} type='text/javascript' />];
|
||||
|
||||
export default sassjs;
|
@ -16,6 +16,7 @@ import presetReact from '@babel/preset-react';
|
||||
import protect from 'loop-protect';
|
||||
|
||||
import * as vinyl from '../utils/polyvinyl.js';
|
||||
import WorkerExecutor from '../utils/worker-executor';
|
||||
|
||||
const protectTimeout = 100;
|
||||
Babel.registerPlugin('loopProtection', protect(protectTimeout));
|
||||
@ -74,27 +75,21 @@ export const babelTransformer = cond([
|
||||
[stubTrue, identity]
|
||||
]);
|
||||
|
||||
const sass = new WorkerExecutor('sass');
|
||||
|
||||
const htmlSassTransformCode = file => {
|
||||
let doc = document.implementation.createHTMLDocument();
|
||||
doc.body.innerHTML = file.contents;
|
||||
let styleTags = [].filter.call(
|
||||
doc.querySelectorAll('style'),
|
||||
style => style.type === 'text/sass'
|
||||
);
|
||||
if (styleTags.length === 0 || typeof Sass === 'undefined') {
|
||||
return vinyl.transformContents(() => doc.body.innerHTML, file);
|
||||
const div = document.createElement('div');
|
||||
div.innerHTML = file.contents;
|
||||
const styleTags = div.querySelectorAll('style[type="text/sass"]');
|
||||
if (styleTags.length > 0) {
|
||||
return Promise.all([].map.call(styleTags, async style => {
|
||||
style.type = 'text/css';
|
||||
style.innerHTML = await sass.execute(style.innerHTML, 2000);
|
||||
})).then(() => (
|
||||
vinyl.transformContents(() => div.innerHTML, file)
|
||||
));
|
||||
}
|
||||
return Promise.all(styleTags.map(style => (
|
||||
new Promise(resolve => {
|
||||
window.Sass.compile(style.innerHTML, function(result) {
|
||||
style.type = 'text/css';
|
||||
style.innerHTML = result.text;
|
||||
resolve();
|
||||
});
|
||||
})
|
||||
))).then(() => (
|
||||
vinyl.transformContents(() => doc.body.innerHTML, file)
|
||||
));
|
||||
return vinyl.transformContents(() => div.innerHTML, file);
|
||||
};
|
||||
|
||||
export const htmlSassTransformer = cond([
|
||||
|
45
client/src/templates/Challenges/utils/worker-executor.js
Normal file
45
client/src/templates/Challenges/utils/worker-executor.js
Normal file
@ -0,0 +1,45 @@
|
||||
export default class WorkerExecutor {
|
||||
constructor(workerName) {
|
||||
this.workerName = workerName;
|
||||
this.worker = null;
|
||||
}
|
||||
|
||||
getWorker() {
|
||||
if (this.worker === null) {
|
||||
this.worker = new Worker(`js/${this.workerName}.js`);
|
||||
}
|
||||
|
||||
return this.worker;
|
||||
}
|
||||
|
||||
killWorker() {
|
||||
if (this.worker !== null) {
|
||||
this.worker.terminate();
|
||||
this.worker = null;
|
||||
}
|
||||
}
|
||||
|
||||
execute(data, timeout = 1000) {
|
||||
const worker = this.getWorker();
|
||||
return new Promise((resolve, reject) => {
|
||||
// Handle timeout
|
||||
const timeoutId = setTimeout(() => {
|
||||
this.killWorker();
|
||||
reject('timeout');
|
||||
}, timeout);
|
||||
|
||||
worker.postMessage(data);
|
||||
|
||||
// Handle result
|
||||
worker.onmessage = e => {
|
||||
clearTimeout(timeoutId);
|
||||
resolve(e.data);
|
||||
};
|
||||
|
||||
worker.onerror = e => {
|
||||
clearTimeout(timeoutId);
|
||||
reject(e.message);
|
||||
};
|
||||
});
|
||||
}
|
||||
}
|
@ -4,10 +4,12 @@ module.exports = (env = {}) => {
|
||||
const __DEV__ = env.production !== true;
|
||||
return {
|
||||
mode: __DEV__ ? 'development' : 'production',
|
||||
entry: './src/client/frame-runner.js',
|
||||
entry: {
|
||||
'frame-runner': './src/client/frame-runner.js',
|
||||
sass: './src/client/workers/sass.js'
|
||||
},
|
||||
devtool: __DEV__ ? 'inline-source-map' : 'source-map',
|
||||
output: {
|
||||
filename: 'frame-runner.js',
|
||||
path: path.join(__dirname, './static/js')
|
||||
},
|
||||
stats: {
|
||||
|
Loading…
x
Reference in New Issue
Block a user