React JSX + Titaniumifier - javascript

Our current infrastructure relies on Titanium for native. I am trying to convert my node project into CommonJS using https://www.npmjs.com/package/grunt-titaniumifier . However, it fails on the JSX:
return (
<div className="App">
<EnergyChart width="1000" data={JSONData.data} customerID={customerID} lineColor='#FF0' height="500" marginTop="20" marginLeft="50" marginBottom="20" marginRight="20" />
</div>
);
Browserify works fine, as it uses the transform like so:
browserify: {
app: {
src: 'app/App.js', dest: 'dist/bundle.js',
options: {
transform: ['grunt-less-browserify', require('grunt-react').browserify],
}
},
}
For titaniumifier, I have the following:
"titaniumifier": {
"module": {
files: {
// The package is in "." and the zipfile will be written in "."
".": "."
},
},
options: {
transform: [ require('grunt-react').browserify],
}
}
However running grunt titaniumifier:module returns
Fatal error: Parsing file
/Users/rduckworth/Projects/titanium-d3/app/App.js: Unexpected token
(23:6)
which is the JSX code above.
Is there anyway I can get Titaniumifier to compile the JSX like browserify does?

#rickyduck Creator and maintainer of titaniumifier here. I’m so sorry I missed this question.
You can enable Babel transpilation for you package/module by using the same syntax I show on the Wiki for enabling it for your app.
Long story short:
Add Babel as a dependency
Use the titaniumifier.transforms object of your package.json
An example:
{
"devDependencies": { ".." },
"titaniumifier": {
"transforms": {
"babel": { "presets": [ "es2015" ] }
}
}
}

Related

Webpack 4 + Angular 10 custom webpack: search and replace loader not working

So I'm trying to use a custom webpack config in my Angular 10.x app where I want to remove 'data-test' attributes from my templates during compilation, so the production code does not contain any e2e selector references. For this, I'm using the custom webpack builder (https://www.npmjs.com/package/#angular-builders/custom-webpack) with a custom webpack config. I'm loading the config in the angular.json like this:
"builder": "#angular-builders/custom-webpack:browser",
"options": {
"customWebpackConfig": {
"path": "./extra-webpack.config.ts",
"mergeStrategies": {
"externals": "append"
}
},
And the webpack config looks like this:
import { CustomWebpackBrowserSchema, TargetOptions } from '#angular-builders/custom-webpack';
import { EnvironmentType, getEnumValues } from '#enum-package/core/enumeration';
import * as webpack from 'webpack';
export default (config: webpack.Configuration, options: CustomWebpackBrowserSchema, targetOptions: TargetOptions) => {
const env: EnvironmentType =
<EnvironmentType>(
getEnumValues(EnvironmentType).find(environmentType =>
targetOptions.configuration?.toLowerCase().includes(environmentType.toLowerCase()),
)
) ?? EnvironmentType.DEVELOPMENT;
if (config.module?.rules) {
// Remove E2E testing attributes from production code
if (env === EnvironmentType.PRODUCTION) {
const testSelectorRegex = new RegExp(/data-test="(.*)"|#HostBinding\('attr.data-test'\)(.*);/g);
config.module.rules.push({
test: /\.(js|ts|html)$/,
enforce: 'pre',
loader: 'string-replace-loader',
options: {
search: testSelectorRegex.source,
replace: match => {
console.log(`Replace E2E selector '${match}'.`);
return ' ';
},
flags: 'g',
},
});
}
}
return config;
};
The search-replace-loader package (https://www.npmjs.com/package/string-replace-loader) is what takes care of replacing the actual attributes from the templates. While running the ng build command, I can actually see that the replace itself works, since the Replace E2E selector '${match}'. is actually running and I can see the tags that I want to remove being logged during compilation.
For some reason when running the app from the dist folder after compilation, the tags are still in place when I inspect the DOM in my browser.
Am I missing something? Is there a build step before or after running this webpack loader that does not use the replaced source code? Does this have anything to do with the Ivy build engine that we're using?

Exported TypeScript Class not included in WebPack bundle if not used directly

I'm converting a javascript project with Angular 1.x to WebPack and TypeScript (using ts-loader). I got it mostly working, but I'm running into trouble when ts-loader seems to be optimizing my scripts out of the bundle when the exports are not directly used.
Here's a sample project demonstrating the issue (npm install, webpack, then load index.html and watch the console).
https://github.com/bbottema/webpack-typescript
The logging from ClassA is showing up, but angular is reporting ClassB missing (provider). If you look in bundle.js you'll notice ClassB missing entirely. The difference is ClassA begin use directly after importing, and ClassB is only referenced by type for compilation.
Is it a bug, or is there a way to force ClassB to be included? Or am I going about it wrong? Angular 2 would probably solve this issue, but that's a step too large right now.
Relevant scripts from the project above:
package.json
{
"devDependencies": {
"typescript": "^1.7.5",
"ts-loader": "^0.8.1"
},
"dependencies": {
"angular": "1.4.9"
}
}
webpack.config.js
var path = require('path');
module.exports = {
entry: {
app: './src/entry.ts'
},
output: {
filename: './dist/bundle.js'
},
resolve: {
root: [
path.resolve('./src/my_modules'),
path.resolve('node_modules')
],
extensions: ['', '.ts', '.js']
},
module: {
loaders: [{
test: /\.tsx?$/,
loader: 'ts-loader'
}]
}
};
tsconfig.json
{
"compilerOptions": {
"target": "es5",
"module": "commonjs"
},
"exclude": [
"node_modules"
]
}
index.html
<!doctype html>
<html ng-app="myApp">
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
entry.js
declare var require: any;
'use strict';
import ClassA = require('ClassA');
import ClassB = require('ClassB');
var a:ClassA = new ClassA(); // direct use, this works
var angular = require('angular');
angular.module('myApp', []).
// this compiles as it should, but in runtime the provider will not be packaged and angular will throw an error
run(function(myProvider: ClassB) {
}
);
ClassA.ts
// this line will be logged just fine
console.log('ClassA.ts: if you see this, then ClassA.ts was packaged properly');
class ClassA {
}
export = ClassA;
ClassB.ts
declare var require: any;
// this line is never logged
console.log('ClassB.ts: if you see this, then ClassB.ts was packaged properly');
class ClassB {
}
var angular = require(angular);
angular.module('myApp').service(new ClassB());
export = ClassB;
Turns out you have to signal WebPack to explicitly include a module by adding an extra require call without import statement.
I'm not ready to mangle my .ts files by adding duplicate imports, so I made a generic solution for that using the preprocessor loader:
{
"line": false,
"file": true,
"callbacks": {
"fileName": "all",
"scope": "line",
"callback": "(function fixTs(line, fileName, lineNumber) { return line.replace(/^(import.*(require\\(.*?\\)))/g, '$2;$1'); })"
}]
}
As a proof of concept, this regex version is very limited it only support the following format:
import ClassA = require('ClassA');
// becomes
require('ClassA');import ClassA = require('ClassA');
But it works for me. Similarly, I'm adding the require shim:
{
"fileName": "all",
"scope": "source",
"callback": "(function fixTs(source, fileName) { return 'declare var require: any;' + source; })"
}
I made a sample project with this solution.

Setting up Karma with Browserify to test React (ES6) components

I'm having trouble setting up a test config with Karma + Browserify for some React components. Mentioning code is written in ES6 and I've upgraded to latest Babel version (6+), which I assume is the root of all evil in this config.
Since Babel is now split and has this plugin-based approach (presets), I'm not sure how I should specify this in the karma.conf file.
My current config looks like this:
module.exports = function(config) {
config.set({
basePath: '',
browsers: ['PhantomJS'],
frameworks: ['browserify', 'jasmine'],
files: [
'app/js/**/*',
'app/__tests__/**/*'
],
preprocessors: {
'app/js/**/*': ['browserify'],
'app/__tests__/**/*': ['browserify']
},
browserify: {
debug: true,
transform: ['babelify']
},
singleRun: true
});
};
However this fails with a bundle error (Unexpected token while parsing file...). Also I get You need to include some adapter that implements __karma__.start method! error message.
It's funny that this happens for some very simple components.
Eg simple React file:
import React from 'react';
class FooterComponent extends React.Component {
render() {
return (
<footer>
This is the application's footer
</footer>
);
}
}
export default FooterComponent;
And the test file doesn't even import it. It's just an always passing test like:
describe('Testing `Footer` component.', () => {
describe('Method: none', function() {
it('Should be a passing test', function() {
expect(true).toBe(true);
});
});
});
The Babel/Browserify related packages in package.json are:
{
"babel-preset-es2015": "^6.0.15",
"babel-preset-react": "^6.0.15",
"babelify": "^7.2.0",
"browserify": "^12.0.1",
}
Any ideas are appreciated. Especially since this used to work before upgrading to Babel 6+.
Cheers!
Add a .babelrc file to your root directory:
{
presets: ['es2015', 'react']
}

Grunt with babel and browserify

I have a simple JavaScript project that uses Babel to transpile ECMAScript 6 to ES5 and then needs Browserify to take advantage of ES6's Modules.
As so, I came up with this Gruntfile.js to compile it:
module.exports = function(grunt) {
"use strict";
grunt.loadNpmTasks('grunt-babel');
grunt.loadNpmTasks('grunt-browserify');
grunt.initConfig({
"babel": {
options: {
sourceMap: true
},
dist: {
files: {
"lib/pentagine.js": "lib/pentagine_babel.js",
"demos/helicopter_game/PlayState.js": "demos/helicopter_game/PlayState_babel.js"
}
}
},
"browserify": {
dist: {
files: {
"lib/pentagine.js": "lib/pentagine_babel.js",
"demos/helicopter_game/PlayState.js": "demos/helicopter_game/PlayState_babel.js"
}
}
}
});
grunt.registerTask("default", ["babel", "browserify"]);
};
grunt runs just fine without any errors. However, I get the following errors:
Uncaught SyntaxError: Unexpected reserved word on export
Uncaught SyntaxError: Unexpected reserved word on import
Basically what I'm doing in the main file is the following:
export class Game {
...
}
And then importing it like:
import {Sprite, Game} from "lib/pentagine";
I'm doing all the code according to ECMAScript 6. However, the export/import does not seem to be working and is instead colliding with JavaScript reserved words (despite me having browserify.js working).
Shouldn't you browserify the files created after the babel task? Note that the property name is the destination file and the value after the : is the source file. (I assume that your ES6 files are called filename.js instead of filename_babel.js)
files: {
"destination_file": "src_file"
}
Which leads to:
grunt.initConfig({
"babel": {
options: {
sourceMap: true
},
dist: {
files: {
"lib/pentagine_babel.js": "lib/pentagine.js",
"demos/helicopter_game/PlayState_babel.js": "demos/helicopter_game/PlayState.js"
}
}
},
"browserify": {
dist: {
files: {
"lib/pentagine_browserified.js": "lib/pentagine_babel.js",
"demos/helicopter_game/PlayState_browserified.js": "demos/helicopter_game/PlayState_babel.js"
}
}
}
});
or just lib/pentagine_babel.js": "lib/pentagine_babel.js" to browserify the same file.

Browserify Shim Buffer core module

I'm trying to browserify my library where there are Buffer core module being use in different places.
I want to shim this core Buffer with another library that we are using.
I have tried to look into https://github.com/thlorenz/browserify-shim where I can specify my module that I want to shim but it doesn't seem to work.
I've created file called shim.js
var Buffer = require('myModule').Buffer;
module.exports = {
Buffer: { exports: Buffer }
};
in Package.json
{
...
"dependencies": {
"MD5": "^1.2.1",
"browser-request": "^0.3.1",
"browserify-shim": "^3.6.0",
...
},
"devDependencies": {
...
},
"browserify-shim": "./shims.js"
}
And in Gruntfile.js (I'm using grunt-browserify)
browserify: {
src: "./index.js",
options: {
transform: ['browserify-shim'],
browserifyOptions: {
builtins: false
},
bundleOptions: {
standalone: "mylibrary"
}
}
}
},
Right now when I grunt build the file I'm still seeing this being require in:
[function(_dereq_,module,exports){
(function (Buffer){
And in my browser is complaining about
Uncaught Error: Module name "buffer" has not been loaded yet for context: _. Use require([])

Categories