Js minification does not work when module has exports - javascript

I do have following Errors when js file is minified
/* Minification failed. Returning unminified contents.
(36307,7-8): run-time error JS1010: Expected identifier: .
(36307,7-8): run-time error JS1195: Expected expression: .
(36817,7-8): run-time error JS1010: Expected identifier: .
(36817,7-8): run-time error JS1195: Expected expression: .
(36820,7-8): run-time error JS1010: Expected identifier: .
(36820,7-8): run-time error JS1195: Expected expression: .
*/
The JavaScript file script file below,
However I found the JavaScript that contains "module.export"
will not be minified and I also use
online tool
for minification, but the minified file does not contain "module.export"
and it is removed
during minification. Any help how to sort the minification problem of JavaScript file contain module.export
(function e(t, n, r) {
module.exports = FilterCSS;
}, {
"./default": 7,
"./parser": 9,
"./util": 10
}], 7: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
function getDefaultWhiteList() {
// ??????:
// true: ?????
// Function: function (val) { } ??true???????,?????????
// RegExp: regexp.test(val) ??true???????,?????????
// ??????????????
var whiteList = {};
whiteList['align-content'] = false; // default: auto
whiteList['align-items'] = false; // default: auto
*
*
#param {
String
}
name
*
#param {
String
}
value
*
#param {
Object
}
options
*
#return {
String
}
*/
function onAttr(name, value, options) {
// do nothing
}
/**
* ???????????????
*
* #param {String} name
* #param {String} value
* #param {Object} options
* #return {String}
*/
function onIgnoreAttr(name, value, options) {
// do nothing
}
var REGEXP_URL_JAVASCRIPT = /javascript\s*\:/img;
/**
* ?????
*
* #param {String} name
* #param {String} value
* #return {String}
*/
function safeAttrValue(name, value) {
if (REGEXP_URL_JAVASCRIPT.test(value)) return '';
return value;
}
exports.whiteList = getDefaultWhiteList();
exports.getDefaultWhiteList = getDefaultWhiteList;
exports.onAttr = onAttr;
exports.onIgnoreAttr = onIgnoreAttr;
exports.safeAttrValue = safeAttrValue;
}, {}], 8: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
var DEFAULT = require('./default');
var FilterCSS = require('./css');
/**
* XSS??
*
* #param {String} css ????CSS??
* #param {Object} options ??:whiteList, onAttr, onIgnoreAttr
* #return {String}
*/
function filterCSS(html, options) {
var xss = new FilterCSS(options);
return xss.process(html);
}
// ??
exports = module.exports = filterCSS;
exports.FilterCSS = FilterCSS;
for (var i in DEFAULT) exports[i] = DEFAULT[i];
// ???????
if (typeof window !== 'undefined') {
window.filterCSS = module.exports;
}
}, {
"./css": 6,
"./default": 7
}], 9: [function(require, module, exports) {
/**
* cssfilter
*
* #author ??<leizongmin#gmail.com>
*/
var _ = require('./util');

Try like this:
['module'].exports = FilterCSS;
Also this:
[module].exports = FilterCSS;
It worked for me, but no idea why.
Before this epiphany, I had solve similar issues with global variables, using something like this:
window['module'].exports=......
But, at least in my case, module was no global.
No idea how I came up with this, and less idea how it worked. I'm new with javascript.

Related

Closure compiler warns about object being not iterable when it really is

I am trying to make something like Java's enum. It works perfectly, but when I try to compile it with ClosureCompiler, I get this warning:
F:\Site\_data\test-ccomp>ccomp -O ADVANCED --js source.js --js_output_file compiled.js
source.js:49:18: WARNING - [JSC_TYPE_MISMATCH] Can only iterate over a (non-null) Iterable type
found : (typeof Color)
required: Iterable
49| for( const clr of Color ) {
^^^^^
0 error(s), 1 warning(s), 87.2% typed
How to get rid of it? Which annotations to use?
If I make Color an object, not a function, with properties RED, GREEN, BLUE of some ColorObj type, and [Symbol.iterator] to iterate over them, it is still the same warning.
//////////////////
// Color type
//////////////////
/**
* For id generation.
*/
let color_counter = 0;
/**
* #constructor
* #param {string} txt Color name.
*/
function Color(txt) {
const id = color_counter++;
const text = txt;
this.ordinal = function() {
return id;
}
this.name = function() {
return text;
}
}
/**
* #const
* #type {Color}
*/
Color.BLUE = new Color("blue");
/**
* #const
* #type {Color}
*/
Color.RED = new Color("red");
/**
* #const
* #type {Color}
*/
Color.YELLOW = new Color("yellow");
/**
* What to annotate here for warning to go away?!
*/
Color[Symbol.iterator] = function*() {
yield Color.BLUE;
yield Color.RED;
yield Color.YELLOW;
}
///////////////////
// Test program
///////////////////
console.info("Colors:");
for (const clr of Color) {
console.info(" - " + clr.name());
}
console.info("Color.BLUE is " + Color.BLUE.name());
console.info("Color.RED is " + Color.RED.name());

Problems in typing eslint-local-rules with jsdoc

I'm trying to type the eslint-local-rules.js file using jsdoc, but I can't figure out how to make #template with the default value for the RuleFunction. My goal is to remove the import('#typescript-eslint/utils/dist/ts-eslint') from the #type of the ArrowFunctionExpression class, but if I use the current typedef RuleFunction, its value will be
but I want to get as from the library
/**
* #typedef {import('#typescript-eslint/utils/dist/ts-estree').TSESTree} TSESTree
* FIXME: how to make the default template TSESTree.BaseNode?
* // # template {TSESTree.BaseNode=} T
* #typedef {import('#typescript-eslint/utils/dist/ts-eslint').RuleContext} RuleContext
* #typedef {import('#typescript-eslint/utils/dist/ts-eslint').RuleFunction} RuleFunction<T>
*/
module.exports = {
'end-api-functions-with-api': {
/**
* #param {Readonly<RuleContext<string, unknown[]>>} context
* #returns
*/
create(context) {
/**
* absolute file path
* #type {string}
*/
const filename = context.getFilename()
/**
* current working directory
* #type {string | undefined}
*/
const cwd = context.getCwd?.()
const relativeFilePath = filename.replace(cwd || '', '')
const fileInApiDirectory = /src\/.*api\//.test(relativeFilePath)
return {
/**
* #type {import('#typescript-eslint/utils/dist/ts-eslint').RuleFunction<import('#typescript-eslint/utils/dist/ts-estree').TSESTree.ArrowFunctionExpression>}
* #returns
*/
ArrowFunctionExpression(node) {

babel renamed function param isn't matching jsdoc

I have a js function:
/**
*
* #param {Object} obj function gets on param - an object
* #param {Number} obj.param1 - 1st num
* #param {Number} obj.param2 - 2nd num
*
* #returns {Number} - the result of the request
*/
const myFunc = ({ param1, param2 }) => {
return param1 * param2
}
After compiling it with babel I get:
/**
*
* #param {Object} obj function gets on param - an object
* #param {Number} obj.param1 - 1st num
* #param {Number} obj.param2 - 2nd num
*
* #returns {Number} - the result of the request
*/
var myFunc = (_ref) => {
var param1 = _ref.param1,
param2 = _ref.param2
return param1 * param2
}
At this point jsdoc is breaking because it is not connecting the jsdoc declaration to the function below anymore.
I also tried to use #function with #name but still no success.
I want to be able to see the relevant param type and comment when using the compiled version. Any idea how can I keep it consistent?
Thanks

Javascript Prototype/Class Function Which Checks Object for Matching Data Returning Undefined

I'm doing a coding challenge and I'm having difficulty returning anything besides undefined. Instead of true or false from the function defined after
Logger.prototype.shouldPrintMessage = function(timestamp, message)
I use MD5 Hashing to match if an exact message has been sent prior.
It's probably something obvious but I don't have enough experience with class/constructor functions.
You need to copy and paste the MD5 Hash function to the top of the code for it to work. You can find it in the first comment of this code.
// MD5 Hash
// Taken from : http://www.myersdaily.org/joseph/javascript/md5-text.html
// Paste Here
/**
* Initialize your data structure here.
*/
var Logger = function() {
this.messageStore = {}
};
/**
* Returns true if the message should be printed in the given timestamp, otherwise returns false.
If this method returns false, the message will not be printed.
The timestamp is in seconds granularity.
* #param {number} timestamp
* #param {string} message
* #return {boolean}
*/
Logger.prototype.shouldPrintMessage = function(timestamp, message) {
let hashedMessage = md5(message);
if (!(hashedMessage in this.messageStore)){
this.messageStore[message] = timestamp;
} else if ((timestamp - this.messageStore.hashedMessage) > 9) {
return true;
}
else if ((timestamp - this.messageStore.hashedMessage) < 10) {
return false;
}
else {
return undefined;
}
};
/**
* Your Logger object will be instantiated and called as such:
* var obj = new Logger()
* var param_1 = obj.shouldPrintMessage(timestamp,message)
*/
var obj = new Logger();
console.log(obj.shouldPrintMessage(1,"foo"));
console.log(obj.shouldPrintMessage(2,"bar"));
console.log(obj.shouldPrintMessage(3,"foo"));
console.log(obj.shouldPrintMessage(8,"bar"));
console.log(obj.shouldPrintMessage(10,"foo"));
console.log(obj.shouldPrintMessage(11,"foo"));
You need to do this.messageStore[hashedMessage] = timestamp; since that is what you are storing it as, and then anywhere you do this.messageStore.hashedMessage you need to do this.messageStore[hashedMessage']:
// MD5 Hash
// Taken from : http://www.myersdaily.org/joseph/javascript/md5-text.html
// Paste Here
md5 = window.btoa;
/**
* Initialize your data structure here.
*/
var Logger = function() {
this.messageStore = {}
};
/**
* Returns true if the message should be printed in the given timestamp, otherwise returns false.
If this method returns false, the message will not be printed.
The timestamp is in seconds granularity.
* #param {number} timestamp
* #param {string} message
* #return {boolean}
*/
Logger.prototype.shouldPrintMessage = function(timestamp, message) {
let hashedMessage = md5(message);
if (!(hashedMessage in this.messageStore)){
this.messageStore[hashedMessage] = timestamp;
return;
} else if ((timestamp - this.messageStore[hashedMessage]) > 9) {
return true;
}
else if ((timestamp - this.messageStore[hashedMessage]) < 10) {
return false;
}
};
/**
* Your Logger object will be instantiated and called as such:
* var obj = new Logger()
* var param_1 = obj.shouldPrintMessage(timestamp,message)
*/
var obj = new Logger();
console.log(obj.shouldPrintMessage(1,"foo"));
console.log(obj.shouldPrintMessage(2,"bar"));
console.log(obj.shouldPrintMessage(3,"foo"));
console.log(obj.shouldPrintMessage(8,"bar"));
console.log(obj.shouldPrintMessage(10,"foo"));
console.log(obj.shouldPrintMessage(11,"foo"));

Issue with offset while reading code points

Resume: I'm currently writting an ActionScript 3 lexer that transforms a source code into tokens. I chosen to interpret the input, a String with optional surrogate pairs wrapped in a class UString, by code points. Under the hood I cache the last read position by using the UStringPos class.
I've tested how it scans the identifier "huehuehue" with...
'use strict';
import {Lexer} from 'core/Lexer';
import {UString} from 'utils/UString';
import ErrorHandler from 'core/ErrorHandler';
const errorHandler = new ErrorHandler(true);
// Tell the length to the `Lexer` manually.
const lexer = new Lexer(
new UString('huehuehue'), 9, errorHandler);
// Scan first token
lexer.next();
const id = lexer.lookahead.value;
console.log(
id,
id.length
);
It should have logged "huehuehue", 9, but was another story...
Why is it missing the last 'e'? The innermost method related on scanning this is Lexer#getCommonIdentifier. I've already tested my UString part and it works okay, by the way.
Lexer Related Definitions
/*
* Class that turns AS3 code into tokens.
*/
export class Lexer
{
/*
* #param {UString} source
* #param {Number} length
* #param {ErrorHandler} errorHandler
*/
constructor(source, length, errorHandler)
{
this.source = source;
this.length = length;
this.index = 0;
this.lineStart = 0;
this.lineNumber = 1;
this.comments = [];
this.errorHandler = errorHandler;
this.previousToken = null;
this.token = null;
this.lookahead = null;
this._special = [];
}
/*
* Verifies the end of file.
*/
eof()
{
return this.index >= this.length;
}
/*
* Advance the previous, current and lookahead tokens.
* The lexer however does not depend on these tokens.
*/
next()
{
this.previousToken = this.token;
this.token = this.lookahead;
this.lookahead = this.lex();
}
/*
* Consumes the next token and return it.
*/
lex()
{
this.consumeWhiteSpaces();
while (this.consumeComment())
this.consumeWhiteSpaces();
let cp = this.source.codePointAt(this.index);
let pureIdentifier =
Character.isIdentifierStart(cp);
if (pureIdentifier || (cp === 0x5C))
return this.scanIdentifierOrKeyword(!pureIdentifier);
if (this.eof())
{
let loc = [ this.index, this.lineNumber ];
return new Token(TokenType.EOF, loc, loc, '<end>');
}
}
/*
* Scan an identifier, keyword or boolean literal.
*/
scanIdentifierOrKeyword(usingEscape)
{
const start = this.index;
let id;
/* Like Esprima does: only identifiers containing
* escapes need some overheads. */
if (usingEscape)
{
id = this.getEscapedIdentifier(
String.fromCodePoint(this.scanUnicodeEscapeSequence()));
}
else
id = this.getCommonIdentifier();
return new Token(
TokenType.IDENTIFIER,
[ start , this.lineNumber ],
[ this.index, this.lineNumber ],
id
);
}
/*
* Interprets an identifier. If any escape appears, switches to
* getEscapedIdentifier().
*/
getCommonIdentifier()
{
const start = this.source.position.offset;
let cp = 0;
// Jump the starting symbol.
++this.index;
while (!this.eof())
{
cp = this.source.codePointAt(this.index);
if (Character.isIdentifierPart(cp))
++this.index;
// Switches to escape-minded task...
else if (cp === 0x5C)
return this.getUnicodeEscapedIdentifier(
this.source.string.slice(
start, this.source.position.offset
)
);
else break;
}
return this.source.string.slice(
start, this.source.position.offset
);
}
/* ... */
}
utils/UString.js
'use strict';
/*
* String wrapper with methods _based_ on code points.
*/
export class UString
{
/*
* Constructs the {UString}.
*
* #param {String} s String to be wrapped.
*/
constructor(s)
{
/*
* #type {String}
*/
this.string = s;
/*
* Tracks the last accessed position.
*
* #type {UStringPos}
*/
this.position = new UStringPos(0, 0);
}
/*
* Reads a code point at specific index.
*
* #param {Number} index
* #return {Number}
*/
codePointAt(index)
{
this.position.walk(this.string, index);
return this.string.codePointAt(this.position.offset);
}
/*
* Slices the internal string by code point indices.
*
* #param {Number} i
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, i);
i = this.position.offset;
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};
/*
* Class that tracks the position of a code point on a string.
*/
export class UStringPos
{
/*
* Constructs the {UStringPos}.
*
* #param {Number} index The initial index.
* #param {Number} offset The initial offset.
*/
constructor(index, offset)
{
/*
* #type {Number}
*/
this.index = index;
/*
* #type {Number}
*/
this.offset = offset;
}
/*
* Walks to the given index.
*
* #param {String} s
* #param {Number} index
* #note No backward. Track the previous position instead.
* #return {void}
*/
walk(s, index)
{
for (; this.index < index; ++this.index)
this.offset += (
this._usingSurrogates(
s.charCodeAt(this.offset)
) ? 2 : 1
);
}
/*
* #private
*/
_usingSurrogates(ch)
{
return (ch >= 0xD800) && (ch <= 0xDBFF);
}
};
Anything?
Okay. So it was a problem with this.source.position.offset: when I do ++this.index, the offset of my UStringPos doesn't update. The problem was with the slice thing.
this.source.string.slice(
start, this.source.position.offset
);
This slice was based on offsets, since I had to track the previous offset where the identifier started.
Solution
I can use the slice of my own UString class and use the first parameter as an offset and the last one as a normal index.
'use strict';
export class UString
{
// ...
/*
* Slices the internal string by using a pair of
* offset and code point indices.
*
* #param {Number} i Offset
* #param {Number} j
* #return {String}
*/
slice(i, j)
{
this.position.walk(this.string, j);
j = this.position.offset;
return this.string.slice(i, j);
}
};

Categories

Resources