Webpack override behavior of require - json

I have a module I'm importing during my webpack that does something like so:
'use strict';
module.exports = {
position: true,
gfm: true,
commonmark: false,
footnotes: false,
pedantic: false,
blocks: require('./block-elements.json')
};
Webpack rewrites this module like so:
module.exports = {
position: true,
gfm: true,
commonmark: false,
footnotes: false,
pedantic: false,
blocks: __webpack_require__(/*! ./block-elements.json */ "./block-elements.json")
};
Another function is then assuming that the blocks member is a string.
Is there a way to override the writing of the webpack_require and replace it with my own function that loads the json in a string?

Finally fixed by writing my own loader and setting the default property on the module exports explicitly.
// Code for the loader
module.exports = function(source) {
// Just inline the source and fix up defaults so that they don't
// mess up the logic in the setOptions.js file
return `module.exports = ${source}\nmodule.exports.default = false`;
}
The other script was enumerating the keys of the returned object and the 'default' key was messing it up. However if a key had a type of Boolean it would let it through.
Specifically it was a problem with the remark-parser lib used for hosting markdown in a react control.

Related

Rest-spread not being transpiled when targeting edge with NextJS

I am trying to transpile my ES6 code via Babel, I am using the next/babel preset along with preset-env and I'm using the browsers: defaults target.
The NextJS preset comes with #babel/plugin-proposal-object-rest-spread in its plugins array, I'm wondering why I am getting an error when testing on edge that says Expected identifier, string or number, and when looking in the compiled JS for the error, I see it happens when {...t} occurs.
Here is my babel.config.js:
module.exports = {
presets: [
[
'next/babel',
{
'#babel/preset-env': {
targets: {
browsers: 'defaults'
},
useBuiltIns: 'usage'
}
}
]
],
plugins: [
'#babel/plugin-proposal-optional-chaining',
'#babel/plugin-proposal-nullish-coalescing-operator',
['styled-components', { ssr: true, displayName: true, preprocess: false }],
[
'module-resolver',
{
root: ['.', './src']
}
]
],
env: {
development: {
compact: false
}
}
};
Any help on this would be greatly appreciated!
In the end my problem was related to a package that was not being transpiled by babel. My solution was to use NextJS' next-transpile-modules plugin to get babel to transpile the package code into something that would work on the browsers I need.
Here's an example of my NextJS webpack config with the package I need transpiled specified:
const withTM = require('next-transpile-modules');
module.exports = withTM({
transpileModules: ['swipe-listener']
});
SCRIPT1028: Expected identifier, string or number error can occur in 2 situations.
(1) This error get trigger if you are using trailing comma after your last property in a JavaScript object.
Example:
var message = {
title: 'Login Unsuccessful',
};
(2) This error get trigger if you are using a JavaScript reserved word as a property name.
Example:
var message = {
class: 'error'
};
solution is to pass the class property value as a string. You will need to use bracket notation, however, to call the property in your script.
Reference:
ERROR : SCRIPT1028: Expected identifier, string or number

bundling CesiumJS using RollupJS

I am trying to bundle CesiumJS with Rollup. I thought I could just do an import like this:
import Cesium from 'cesium/Build/Cesium/Cesium.js'
with the following rollup.config.js file. I am getting a bundle.js but when I run it I get lots errors:
Uncaught TypeError: Cannot read property 'document' of undefined
at bundle.js:formatted:102314
function() {
!function(e) {
var t = this || eval("this")
, r = t.document // it is complaining on this line
, i = t.navigator
, n = t.jQuery
, o = t.JSON;
rollup.config.js
import resolve from 'rollup-plugin-node-resolve'
import commonjs from 'rollup-plugin-commonjs'
import uglify from 'rollup-plugin-uglify'
import { minify } from 'uglify-es'
export default {
input: 'scripts/Main.js',
output: {
file: 'dist/bundle.js',
format: 'es',
},
"options": {
sourceMap: 'inline',
output: {
format: 'es'
}
},
plugins: [
resolve({
jsnext: true,
main: true,
browser: true,
}),
commonjs(),
uglify({}, minify)
]
}
ES modules are always in strict mode — by extension, when something is imported into Rollup and converted to an ES module, it also runs in strict mode.
In strict mode, the value of this inside a function is undefined, unless it's a) called as a method, or b) explicitly set with call or apply.
This is expected behaviour with Rollup, and it isn't technically a bug with Cesium, but I would suggest raising an issue with them and seeing if they can use a more modern way of accessing the global variable. There's really no reason to be relying on non-strict behaviour in 2017!
As a last resort you could string-replace this || eval("this") (or this||(0,eval)("this"), as it is in the minified version) with window.
If there are lots of other errors after making that change, it may be impossible to include Cesium in your bundle, and you would need to keep it as an external module.

TreeStore: different behaviour beetween autoLoad configuration and load() function

The test case in fiddle is working with autoLoad: true but with autoLoad: false (line 86) the load() function called at line 161 in the TreePanel beforerender event does not load the data...
For (non tree) panels I allways have set autoLoad to false and load the store on render of the GridPanel and it works perfectly. I do it like this to prevent loading all the stores at the beginning (and to set filters sometimes).
The beforeload event of the store is preventing double-load.
Where is my fault for this TreeStore ? I am looking for a solution for a long time without any result...
There has been similar issue in Ext JS 4 explained here ExtJS 4. Hidden treepanel with autoload false .
What I did in your fiddle is that I just added the following
autoLoad: false,
root:{
//expanded: true, // optional
children: []
}
to line 91 in your store configuration. Everything worked magically.
I think I've solved your problem.
Use the root property for your TreeStore.
/*
* Store
*/
Ext.define('Chronos.store.Clockings', {
extend : 'Ext.data.TreeStore',
requires: [
//'Chronos.store.Session'
],
model : 'Chronos.model.Presence',
autoLoad : false, //true, // false,
//autoSync : true, // DEBUG
sortOnLoad : false,
pageSize : 0,
remoteFilter: true,
root: {
id: 'id',
expanded: true
},
listeners: {
load: function(treestore, records, success) {
console.log(Date(), 'clockings loaded: ', success, treestore);
},
beforeload: function (treestore) {
if(treestore.isLoading()) return false;
}
}
});
Hope this is what you are looking for!

Electron & ES6 how to implement require remote/ipc when using gulp and ES6 modules

i am using ES6 js files that are then compiled by gulp (browserify/babel), example of a ES6 file is:
I have a normal App.js that is used to set up the main window etc.. Then the html pages will use a main.min.js file that is basically made up with all my ES6 classes compiled into one file:
loader.es6 file
import Main from './pages/Main.es6'
new Main()
Main.es6 file
import Vue from 'vue';
export default class Main extends Vue{
constructor() {...}
.....
}
When compiled and run this all works fine and all is good... But as i thought if i want to implement the 'IPC', 'Remote' modules, i am having issues with compiling as they cannot find those modules, either through the require() or import.. methods within my classes.
so doing the following fails:
import Remote from 'remote'
import Main from './pages/Main.es6'
new Main()
or
var Remote = require('remote')
import Main from './pages/Main.es6'
new Main()
Is this possible to do or achieve, or nope needs more thought and going back to normal js please.
Any ideas / advice would be great thanks
EDIT: add the error details
An example file in question Main.es6
see the added var var Remote = require('remote')at the top this causes the following error.
even using import Remote from 'remote'
{ [Error: Cannot find module 'remote' from '/Volumes/DAVIES/ElectronApps/electron-vuejs-starter/resources/js/pages']
stream:
{ _readableState:
{ highWaterMark: 16,
buffer: [],
length: 0,
pipes: [Object],
pipesCount: 1,
flowing: true,
ended: false,
endEmitted: false,
reading: true,
sync: false,
needReadable: true,
emittedReadable: false,
readableListening: false,
objectMode: true,
defaultEncoding: 'utf8',
ranOut: false,
awaitDrain: 0,
readingMore: false,
decoder: null,
encoding: null,
resumeScheduled: false },
readable: true,
domain: null,
_events:
{ end: [Object],
error: [Object],
data: [Function: ondata],
_mutate: [Object] },
_maxListeners: undefined,
_writableState:
{ highWaterMark: 16,
objectMode: true,
needDrain: false,
ending: true,
ended: true,
finished: true,
decodeStrings: true,
defaultEncoding: 'utf8',
length: 0,
writing: false,
corked: 0,
sync: false,
bufferProcessing: false,
onwrite: [Function],
writecb: null,
writelen: 0,
buffer: [],
pendingcb: 0,
prefinished: true,
errorEmitted: false },
writable: true,
allowHalfOpen: true,
_options: { objectMode: true },
_wrapOptions: { objectMode: true },
_streams: [ [Object] ],
length: 1,
label: 'deps' } }
In my case, I'm using browserify with babelify, if I tried:
var remote = require('remote')
I would got error:
Error: Cannot find module 'remote' from xxx
But if I tried
var remote = window.require('remote')
It works.
import remote from 'remote' doesn't work, seems like browserify can't find those native modules not defined in package.json.
Well been playing and I have managed to get this to work in a way:
Basically i set the remote and ipc modules within the html page, then pass in those, into my class for that page.
main.html
<script>
var remote = require('remote');
var ipc = require('ipc');
new Main(ipc);
</script>
Main.js - Class File
export default class Main extends Vue{
constructor(ipc) {
....
ipc.send('listener here','message here');
.....
The files can be viewed within this Branch:
Honestly, the easiest way to solve this is to not minify your binaries or use browserify. Electron already has require in the global scope - all you need to do is run your files through Babel to ES6 => ES5 compile them (electron-compile makes this trivially easy too). Your import statement will get translated to a require, which Electron will automatically handle out of the box.
In general, a lot of optimization strategies that you're used to on the web like minification or concatenation are unnecessary or don't make sense in Electron, you can mostly just not do them!

nodejs ractive and consolidate html comment issue

I am using consolidate.js and ractive templates, which by default strip out comments. I am trying to add some html logic in the page that does something like this:
<![if IE]>one thing<![endif]>
<![if !IE]>another thing<![endif]>
However ractive removes the comments. I know you can allow comments in ractive, by setting stripComments false, but I don't know how to do that through consolidate.js.
The second argument of consolidate.ractive() is passed directly to Ractive, so you can do this:
cons.ractive(path, { stripComments: false, user: 'Tobi' }, function () {});
In case you want to separate your data from Ractive config, you can do this instead:
cons.ractive(path, { stripComments: false, data: { user: 'Tobi' } }, function () {});
If the object doesn't have the data property, the whole object will be used as data as well.