Cannot call functions after running browserify - javascript

I have a an es6 JS class below which I am running through browserify to output in es5. Below is my es6 JS class:
import $j from "jquery";
import BaseComponent from './Components/base-component';
class QuestionnaireView extends BaseComponent {
constructor() {
super();
this.defaultOptions = {
questionId : '#questionId',
responseId : '#responseId',
answerId : '#answerId',
questionTextId : '#questionTextId'
};
this.state = {
};
}
initChildren() {
}
addListeners() {
}
collectQuestions() {
var questionAndAnswersDict = [];
var answersAndWeightingsDict = [];
$j(this.options.questionId).each(function () {
var questionText = $j(this).find("input")[0].value;
$j(this.options.answerId).each(function () {
var answerText = $j(this).find("input")[0].value;
var weighting = $j(this).find("input")[1].value;
answersAndWeightingsDict.push({
key: answerText,
value: weighting
});
});
questionAndAnswersDict.push({
key: questionText,
value: answersAndWeightingsDict
});
});
}
collectResponses() {
var responsesDict = [];
var weightingDict = [];
$j(this.options.responseId).each(function () {
var minWeighting = $j(this).find("input")[0].value;
var maxWeighting = $j(this).find("input")[1].value;
var responseText = $j(this).find("input")[2].value;
weightingDict.push({
key: minWeighting,
value: maxWeighting
});
responsesDict.push({
key: responseText,
value: weightingDict
});
});
}
}
export default () => { return new QuestionnaireView(); };
And here is the browserify command I am running:
browserify Scripts/questionnaire-view.js -o wwwroot/js/questionnaire-view.js
I have also tried
browserify Scripts/questionnaire-view.js -o wwwroot/js/questionnaire-view.js -t [ babelify --presets [ #babel/preset-env #babel/preset-react ] --plugins [ #babel/plugin-transform-modules-commonjs ] ]
The output JS file looks okay and does not throw any errors in dev tools but when I go to call a function I get the following:
Error: Microsoft.JSInterop.JSException: Could not find 'collectQuestions' ('collectQuestions' was undefined).
Error: Could not find 'collectQuestions' ('collectQuestions' was undefined).
at http://localhost:41131/_framework/blazor.server.js:1:288
at Array.forEach (<anonymous>)
at r.findFunction (http://localhost:41131/_framework/blazor.server.js:1:256)
at v (http://localhost:41131/_framework/blazor.server.js:1:1882)
at http://localhost:41131/_framework/blazor.server.js:1:2662
at new Promise (<anonymous>)
at et.beginInvokeJSFromDotNet (http://localhost:41131/_framework/blazor.server.js:1:2643)
at http://localhost:41131/_framework/blazor.server.js:1:62750
at Array.forEach (<anonymous>)
at et._invokeClientMethod (http://localhost:41131/_framework/blazor.server.js:1:62736)
Any help is greatly appreciated :)

I ended up using webpack with babel loader:
var devJSConfig = Object.assign({}, config, {
mode: 'development',
entry: [
path.resolve(__dirname, './Scripts/Components/base-component.js'),
path.resolve(__dirname, './Scripts/address-view.js'),
path.resolve(__dirname, './Scripts/customer-view.js'),
path.resolve(__dirname, './Scripts/questionnaire-view.js')
],
output: {
path: path.resolve(__dirname, 'wwwroot/js'),
filename: "[name].js"
},
module: {
rules: [
{
test: /\.(js|jsx)$/,
exclude: '/node_modules/',
use: [
{
loader: 'babel-loader',
options: {
presets: [
"#babel/preset-env"
]
}
}
]
}
]
}
});
In my _Host.cshtml I had the script tag type attribute for my js files set to 'text/javascript' when it needs to be 'module'. I was also linking the individual script files but only needed to reference the bundle js which was produced using the above.
Lastly in my script I had to expose the js class to the Window like so (place this at the end of your js class):
window['QuestionnaireView'] = new QuestionnaireView();
I could then call js functions in my Blazor component class using:
var test = await jSRuntime.InvokeAsync<Object>("QuestionnaireView.collectQuestions");

Related

How use sql.js-httpvfs library in Gatsby?

I try to use sql.js-httpvfs library inside my project. However, I am not successed yet. I am not expert about node.js.
What I do?
Firstly, need to webpack.config to Gatsby for that I create gatsby-node.js file and add the below code inside it.
exports.onCreateWebpackConfig = ({ actions }) => {
actions.setWebpackConfig({
entry: "./src/index.js",
module: {
rules: [
{
test: "/.tsx?$/",
use: "ts-loader",
exclude: "/node_modules/",
},
],
},
output: {
filename: "bundle.js",
},
devServer: {
publicPath: "/dist",
},
});
};
Inside my index.js page, I add the code;
import { createDbWorker } from "sql.js-httpvfs";
const workerUrl = new URL(
"sql.js-httpvfs/dist/sqlite.worker.js",
import.meta.url
);
const wasmUrl = new URL("sql.js-httpvfs/dist/sql-wasm.wasm", import.meta.url);
function load() {
const worker = createDbWorker(
[
{
from: "inline",
config: {
serverMode: "full",
url: "../myTestDb.sqlite3",
requestChunkSize: 4096,
},
},
],
workerUrl.toString(),
wasmUrl.toString()
);
const result = worker.db.query(`select * from districts`);
document.body.textContent = JSON.stringify(result);
}
load();
But I got error.
There is no any created bundle.js or folder like dist.

How to process compiled Vue's component in webpack?

I want to create a "macro" similar to gettext in Django for Vue.js.
How can I setup a loader so that it will get a compiled (parsed) Vue.js component's template tag? It can be either JS or some AST.
Example:
// webpack.config.js
module.exports = {
module: {
rules: [{
test: /.vue$/,
loader: 'vue-loader'
}, {
test: /.vue?template/ // just an example
loader: myLoader
}]
}
}
// my-loader.js
module.exports = function (source) {
// here source is either JS or AST representation
return source
}
Simple config can look like this:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.vue$/,
use: [
'vue-loader',
'my-loader', // our custom loader
]
}
]
}
}
// my-loader.js
const { createDefaultCompiler } = require('#vue/component-compiler')
module.exports = function(source) {
const compiler = createDefaultCompiler()
const descriptor = compiler.compileToDescriptor('filename.vue', source)
const { template } = descriptor;
console.log(template.ast) // AST of the component's template tag
}

React.js and webpack - why won't it allow var, let, const?

I have a bit of an issue here that I can't get to the bottom of.
Here's a snippet from my Graph.js file:
class Graph extends React.Component {
#observable newTodoTitle = "";
s = 40
There error in webpack is as follows:
ERROR in ./src/components/Graph.js
Module build failed: SyntaxError: Unexpected token (13:6)
2018-01-11T14:56:05.221073500Z
11 |
12 |
> 13 | let s = 40
| ^
If I remove the "let", it compiles fine!
I'd prefer to keep the var, let, consts, etc. as I want to copy and paste a lot of JavaScript into this file without these errors.
Here's my .babelrc
{
"presets": [
"react",
"es2015",
"stage-1"
],
"plugins": ["transform-decorators-legacy"]
}
And here's my webpack.config.js:
var path = require('path');
var webpack = require('webpack');
module.exports = {
devtool: 'eval',
entry: [
'./src/index'
],
output: {
path: path.join(__dirname, 'dist'),
filename: 'bundle.js',
publicPath: '/static/'
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
resolve: {
extensions: ['.js', '.jsx']
},
module: {
rules: [{
test: /\.jsx?$/,
use: ['babel-loader'],
include: path.join(__dirname, 'src')
}]
}
};
Any ideas?
You are trying to use the class-fields proposal (stage 3 currently) which you will need the Class properties transform plugin of babel to support this.
As you can see in the docs, your syntax is off.
There is no need for any variable declaration key word for class fields.
Example from the docs:
class Counter extends HTMLElement {
x = 0;
clicked() {
this.x++;
window.requestAnimationFrame(this.render.bind(this));
}
constructor() {
super();
this.onclick = this.clicked.bind(this);
}
connectedCallback() { this.render(); }
render() {
this.textContent = this.x.toString();
}
}

How to use Webpack and Gulp with multiple entry points to transpile app and test directories?

I am building a basic blog project to practice using React, ES6, and Mocha test framework. I'm having trouble transpiling my ES6 tests and app code within my default Gulp task.
I get this error when I run the default task and change the contents of ./test/posts.js for the watch to take effect:
[11:17:29] Using gulpfile ~/WebstormProjects/blog/gulpfile.js
[11:17:29] Starting 'default'...
[11:17:29] Finished 'default' after 8.54 ms
stream.js:75
throw er; // Unhandled stream error in pipe.
^
Error: invalid argument
at pathToArray (/Users/christian/WebstormProjects/blog/node_modules/memory-fs/lib/MemoryFileSystem.js:44:10)
at MemoryFileSystem.mkdirpSync (/Users/christian/WebstormProjects/blog/node_modules/memory-fs/lib/MemoryFileSystem.js:139:13)
at MemoryFileSystem.(anonymous function) [as mkdirp] (/Users/christian/WebstormProjects/blog/node_modules/memory-fs/lib/MemoryFileSystem.js:279:34)
at Compiler.<anonymous> (/Users/christian/WebstormProjects/blog/node_modules/webpack/lib/Compiler.js:229:25)
at Compiler.applyPluginsAsync (/Users/christian/WebstormProjects/blog/node_modules/tapable/lib/Tapable.js:60:69)
at Compiler.emitAssets (/Users/christian/WebstormProjects/blog/node_modules/webpack/lib/Compiler.js:226:7)
at Watching.<anonymous> (/Users/christian/WebstormProjects/blog/node_modules/webpack/lib/Compiler.js:54:18)
at /Users/christian/WebstormProjects/blog/node_modules/webpack/lib/Compiler.js:403:12
at Compiler.next (/Users/christian/WebstormProjects/blog/node_modules/tapable/lib/Tapable.js:67:11)
at Compiler.<anonymous> (/Users/christian/WebstormProjects/blog/node_modules/webpack/lib/CachePlugin.js:40:4)
Process finished with exit code 1
webpack.config.js
var path = require('path');
var babel = require('babel-loader');
module.exports = {
entry: {
app: './app/js/blog.js',
test: './test/posts.js'
},
output: {
filename: '[name].bundle.js',
path: './build',
sourceMapFilename: '[name].bundle.map'
},
watch: true,
devtool: '#sourcemap',
module: {
loaders: [
{
loader: 'babel',
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
query: {
presets: ['react', 'es2015']
}
}
],
resolve: {
root: path.resolve('./app'),
extensions: ['', '.js']
}
}
};
gulpfile.js
var gulp = require('gulp');
var webpack = require('webpack-stream');
var watch = require('gulp-watch');
var babel = require('babel-loader');
var named = require('vinyl-named');
gulp.task('default', function() {
watch(['./app/**/*.js', './test/*.js'], function() {
return gulp.src(['./app/js/blog.js', './test/posts.js'])
.pipe(named())
.pipe(webpack(require('./webpack.config.js')))
.pipe(gulp.dest('./build'));
});
});
gulp.task('testBundle', function() {
gulp.src('./test/posts.js')
.pipe(webpack(require('./webpack.config.js')))
.pipe(gulp.dest('./build'));
});
posts.js
import expect from 'expect'
import { post, posts, addPost } from '../app/js/blog'
import { createStore } from 'redux'
describe('Blog', () => {
describe('posts', () => {
it('should be able to create a post', () => {
let store = createStore(posts);
store.dispatch(addPost('First Post', 'Blah blah blah'))
let blah = { id: 'First Post', content: 'Blah blah blah'}
expect(store.getState()).toEqual(blah)
});
it('should be able to create multiple posts', () => {
let store2 = createStore(posts);
store2.dispatch(addPost('Second Post', 'Shh'))
let expectedState1 = { id: 'Second Post', content: 'Shh' }
expect(store2.getState()).toEqual(expectedState1)
store2.dispatch(addPost('Third Post', 'Whatever'))
let expectedState2 = { id: 'Third Post', content: 'Whatever'}
expect(store2.getState()).toEqual(expectedState2)
})
});
});
Ultimately, I'd like the transpiled code to be found at ./build/blog.bundle.js and ./build/posts.bundle.js for ./app/js/blog.js and ./test/posts.js, respectively.
There were some issues with my webpack.config.js and gulpfile.js. Apparently, the path property within the output object in webpack.config.js was conflicting with gulp.dest('./build'). I also reformatted some things in the config file to mirror a working one. Below is the code that should work. Hopefully this helps others trying to accomplish the same thing.
I have gulp starting webpack to produce separate bundle files for app and test entry points. I also get sourcemaps for each of the bundles that are created. Now I can write tests and app code in ES6 and run them with Mocha within WebStorm!
gulpfile.js
var gulp = require('gulp');
var webpack = require('webpack-stream');
var watch = require('gulp-watch');
gulp.task('default', function() {
watch(['./app/**/*.js', './test/*.js'], function() {
return gulp.src(['./app/js/blog.js', './test/posts.js'])
.pipe(named())
.pipe(webpack(require('./webpack.config.js')))
.pipe(gulp.dest('./build'));
});
});
gulp.task('webpack', function() {
return gulp.src(['./app/js/blog.js', './test/posts.js'])
.pipe(named())
.pipe(webpack(require('./webpack.config.js')))
.pipe(gulp.dest('./build'));
});
webpack.config.js
var path = require('path');
var babel = require('babel-loader');
module.exports = {
entry: {
app: './app/js/entry.js',
test: './test/posts.js'
},
output: {
filename: '[name].bundle.js',
sourceMapFilename: '[name].bundle.map'
},
devtool: '#source-map',
module: {
loaders: [
{
loader: 'babel',
test: /\.jsx?$/,
exclude: /(node_modules|bower_components)/,
query: {
presets: ['react', 'es2015']
}
}
]
},
resolve: {
root: path.resolve('./app'),
extensions: ['', '.js']
}
};
entry.js
import { posts } from './blog'
import { createStore } from 'redux'
createStore(posts)
blog.js
const posts = (state = [], action) => {
switch (action.type) {
case 'ADD_POST':
return post(undefined, action)
default:
return state
}
}
const post = (state = {}, action) => {
switch (action.type) {
case 'ADD_POST':
return { id: action.name, content: action.content }
}
}
// action creator
const addPost = (name, content) => {
return {
type: 'ADD_POST',
name,
content
}
}
export { posts, post, addPost }

Webpack bundle validates but node server throwing syntax error

I am using webpack to bundle/transform jsx.
From the command line I'm running "webpack --watch". This creates my bundle without errors. Here's my webpack config and Application.js
'use strict';
var webpack = require('webpack');
module.exports = {
resolve: {
extensions: ['', '.js']
},
devtool: 'eval',
entry: './client.js',
output: {
path: __dirname+'/build/js',
filename: 'client.js'
},
module: {
loaders: [
{ test: /\.css$/, loader: 'style!css' },
{ test: /\.js$/, loader: 'jsx-loader?harmony' }
]
}
};
var React = require('react'),
classSet = require('react/addons'),
Nav = require('./Nav.js'),
Home = require('./Home.js'),
Recipe = require('./Recipe.js'),
RecipeArchive = require('./RecipeArchive.js'),
About = require('./About.js'),
Timestamp = require('./Timestamp.js'),
RouterMixin = require('flux-router-component').RouterMixin;
var Application = React.createClass({
mixins: [RouterMixin],
getInitialState: function () {
this.store = this.props.context.getStore('ApplicationStore');
return this.store.getState();
},
componentDidMount: function () {
var self = this;
self._changeEventListener = function () {
var state = self.store.getState();
self.setState(state);
};
self.store.on('change', self._changeEventListener);
},
componentWillUnmount: function () {
var self = this;
self.store.removeListener('change', self._changeEventListener);
self._changeEventListener = null;
},
render: function () {
return (
<div>test</div>
);
}
});
module.exports = Application;
Then I'm running my node server which throws an error.
node server.js
results in:
/Users//Documents/routing/components/Application.js:39
<div>test</div>
^
SyntaxError: Unexpected token <
How should I be running my project to allow me to include jsx/harmony in my .js files?
UPDATE: Solution
As Brandon pointed out, I needed to use node-jsx for transforms in Node. At the top I've of my server.js file I've added and alls working:
require('node-jsx').install({ extension: '.js', harmony: true });
Webpack just creates a client-side bundle; when you run your Node app, it doesn't use webpack to load the files. Prevously you could use something like node-jsx to require JSX files in Node.js, but that project has since been deprecated in favor of Babel. In particular, you can use babel-register to require JSX files in Node.

Categories

Resources