Exception Value: string indices must be integers : Render bundle error vue + django - html

im using webpack loader to inyect my vue app into django, here is the code:
Settings :
WEBPACK_LOADER = {
'DEFAULT':{
'BUNDLE_DIR_NAME':'/',
'STATS_FILE':os.path.join(BASE_DIR,'aptim-frontend/dist','webpack-stats.json')
}}
vue config file :
const BundleTracker = require("webpack-bundle-tracker");
module.exports = {
// on Windows you might want to set publicPath: "http://127.0.0.1:8080/"
publicPath: "http://0.0.0.0:8080/",
outputDir: "./dist/",
chainWebpack: (config) => {
config.optimization.splitChunks(false);
config
.plugin("BundleTracker")
.use(BundleTracker, [{ filename: "../frontend/webpack-stats.json" }]);
config.resolve.alias.set("__STATIC__", "static");
config.devServer
.public("http://0.0.0.0:8080")
.host("0.0.0.0")
.port(8080)
.hotOnly(true)
.watchOptions({ poll: 1000 })
.https(false)
.headers({ "Access-Control-Allow-Origin": ["*"] });},};
And the html line where I get the error is at the index html
{% render_bundle 'app' %}
ERROR :Exception Value: string indices must be integers

I had the same issue in the great Udemy course The Complete Guide to Django REST Framework and Vue JS. You probably cannot read the answer from Michele Saba if you are not subscribed.
It probably has something to do with the package versions and them being alpha. Downgrading to
webpack-bundle-tracker#0.4.3
django-webpack-loader==0.7.0
worked for me. Downgrade using:
npm install --save-dev webpack-bundle-tracker#0.4.3

Downgrade Webpack-bundle-tracker as told by #Frans
npm install --save-dev webpack-bundle-tracker#0.4.3
In vue.config.js
config
.plugin('BundleTracker')
.use(BundleTracker, [{filename: './webpack-stats.json'}])
Then delete the dist folder with the old webpack-stats.json
In this version and with this config webpack-stats.json file is generated in frontend not in frontend/dist
So you must change STATS_FILE in settings.py
(for example if your Vue project is frontend)
'STATS_FILE': os.path.join(BASE_DIR, 'frontend','webpack-stats.json'),
Then restart Vue and Django web-servers.

Exception Value: string indices must be integers
i got this strange error too, confirmed downgrade to webpack-bundle-tracker#0.4.3 works.

Related

Environment Flag for Cucumber Protractor E2E Tests?

I have an existing Angular v5 app and have environment.json files for my environments (like DEV, Test, Production, etc.). The environments files are stored in the directory like so: src/Environments/DEV/environment.json.
Here is an example of a dev environment.json file:
{
"Comment": "Environment=DEV",
"API_ORIGIN": "https://myapp-dev",
"ORIGIN": "https://myapp-dev/index.html",
}
There is a root environment.json file in src folder that my app reads from. When I want to use a specific environment I just copy that environment content into the root and run the app.
Now with Cucumber and Protractor is there a way I can pass some command line argument to specify which environment.json file to use based on my setup? I have urls in these environment.json files so I need a way to tell Cucumber and Protractor which environment to use. If I have to copy all of the environment.json files into the e2e folder that is fine with me. Just in case the solution I need to use depends on the tools I am using here is my tsconfig.e2e.json file. Please let me know if it is incorrect:
{
"extends": "../tsconfig.json",
"compilerOptions": {
"outDir": "../out-tsc/e2e",
"baseUrl": "./",
"module": "commonjs",
"target": "es5",
"types": [
"chai",
"cucumber",
"node"
]
}
}
Here is the protractor.conf.js file. Let me know if it is incorrect as well please:
// Protractor configuration file, see link for more information
// https://github.com/angular/protractor/blob/master/lib/config.ts
exports.config = {
allScriptsTimeout: 11000,
specs: [
'./e2e/features/**/*.feature'
],
capabilities: {
'browserName': 'chrome'
},
directConnect: true,
baseUrl: 'http://localhost:4200/',
framework: 'custom',
frameworkPath: require.resolve('protractor-cucumber-framework'),
cucumberOpts: {
// require step definition files before executing features
require: ['./e2e/steps/**/*.ts'],
// <string[]> (expression) only execute the features or scenarios with tags matching the expression
tags: [],
// <string[]> ("extension:module") require files with the given EXTENSION after requiring MODULE (repeatable)
compiler: []
},
// Enable TypeScript for the tests
onPrepare() {
require('ts-node').register({
project: 'e2e/tsconfig.e2e.json'
});
}
};
I'm also using npm if that matters. I'm running these tests with ng e2e command provided by angular.
sure, 2 ways:
pass a parameter to protractor protractor conf.js --params.env="dev" and then refer to it as browser.params.env in specs. Downside is, it will only be available when the config is parsed and the browser is started, so you can really use that in the config itself
Run the process with an env variable MY_VAR=Dev protractor config.js and it will be available anywhere by running process.env.MY_VAR
For reference
https://stackoverflow.com/a/58547994/9150146
https://stackoverflow.com/a/66111592/9150146
P.S.
how you implement it is up to you, but this approach is the most flexible
conf.js
let environment = require('src/Environments/' + process.env.TEST_ENV + '/environment.json');
module.exports = {
baseUrl: environment.API_ORIGIN
}
and start your protractor like so
TEST_ENV=DEV protractor config.js

Webpack 4 - JSON module not found

I have some JSON files in my Webpack application that I want to import. They have names such as 0.json, 1.json, 2.json, and so on and are inside of the directory src/res/level/. When I try to require() them in my code, it does not work:
private loadWorld() {
// load the level
// duplicate the object to avoid modifying the actual instance
// that json-loader created
this.state.level = JSON.parse(JSON.stringify(require(`#res/level/${this.level}.json`))) as LevelData;
// ...
}
This line in my method always throws an error:
Error: Cannot find module "#res/level/1.json".
at webpackContextResolve (webpack-internal:///9:16:11)
at webpackContext (webpack-internal:///9:9:11)
However, I cannot figure out why. And to make things more confusing, if I run Webpack in watch mode, and I edit this line before my program tries to run it, then the JSON files are suddenly loaded properly.
I have configured my alias for #res properly:
resolve: {
extensions: [".ts", ".js", ".glsl", ".json"],
alias: {
"#res": path.join(__dirname, "src/res"),
"#lib": path.join(__dirname, "src/lib"),
"#shader": path.join(__dirname, "src/shader"),
"#control": path.join(__dirname, "src/control"),
"#scene": path.join(__dirname, "src/scene"),
"#util": path.join(__dirname, "src/util"),
}
}
And because this is Webpack 4, I simply did not include a loader for JSON.
So why is this not working?
Additionally, I notice that when I inspect the generated code, I see this:
Which suggests that the JSON files are being loaded, but not under the directory that I expect.
The compiler began to load the JSON files consistently when I used string concatenation instead of a template string:
this.state.level = JSON.parse(JSON.stringify(require("#res/level/" + this.level.toString() + ".json"))) as LevelData;

Configuring app's basename in react-router

I'm struggling a bit with react-router 2.x configuration, specifically app basename.
I've an application which may have different base root throughout its lifecycle. For instance:
/ in development
/users in production
/account in production after migration
The basename comes into play in several places:
static asset compilation in Webpack
react-router main configuration
specifying redirect routes in redux actions
providing something like redirectUrl to API calls
My current solution is to have an ENV variable and make it available both to Webpack and to the app itself by injecting window.defs via an Express server, but I still end up having things like ${defs.APP_BASENAME}/signin in way too many places throughout the app.
How can I abstract the app base, or at least tuck it away in a single location? I should be able to specify the base route in Router's config, and then simply use relative routes somehow, right? Or am I missing something?
You can decorate your history with a basename. You could mix this with a DefinePlugin in your Webpack configuration to specify which basename should be used.
// webpack.config.js
new Webpack.DefinePlugin({
BASENAME: '/users'
})
// somewhere in your application
import { useRouterHistory } from 'react-router'
import { createHistory } from 'history'
const history = useRouterHistory(createHistory)({
basename: BASENAME
})
Given the basename: /users, React Router will ignore the /users at the beginning of the pathname so:
The URL /users is internally matched by the path /
The URL /users/profile matches the path /profile.
Similarly, you do not have to append the basename to the path when you are navigating within your application.
<Link to='/friends'>Friends</Link> will navigate to /friends internally, but the URL in the location bar will be /users/friends.
Today I ran into the same issue:
On my localhost I let an NGINX serve the stuff in the root context, but on my prod server, an Apache serves the stuff from a subdirectory...
Inspired by the answer from Paul S and inspired by the infos here:
https://github.com/ReactTraining/react-router/issues/353
I got the for me working solution:
In the Webpack config file I defined a plugin for my localhost dev env:
plugins: [
new webpack.DefinePlugin({
BASENAME: JSON.stringify("/")
})
],
In the Webpack PROD config file I defined a plugin for my prod env in a subfolder, i.e. www.example.com/users:
plugins: [
new webpack.DefinePlugin({
BASENAME: JSON.stringify("/users/")
}),
And in my react-router definitions I just reference:
import { Router, Route, IndexRoute, browserHistory } from 'react-router';
import { useBasename } from 'history'
...
<Router history={useBasename(() => browserHistory)({ basename: BASENAME })}>
For me a very elegant solution and easy too. It just cost me around five hours of looking around :-)
In React Router V6.
Edit package.json and add homepage : Directory name key value as follows
"homepage" : "https://blog.sangw.in/react-student-management",
OR
"homepage" : "/react-student-management",
and on Routers BrowserRouter add basename : Directory name as follows
<BrowserRouter basename={'/react-student-management'}>
and you are done.
Visit https://blog.sangw.in/react-student-management and app will be deployed and working.
Try this it will work
import { createBrowserHistory } from 'history';
const history = createBrowserHistory({
basename: 'base-name'
})
<Router history={history}>
</Router>

How to run hapi-lab tests from gulp written using es6 syntax

I am creating a hapi api seed project. I have opted to use es6 syntax in the source of the project. I am using hapi-lab as my testing framework. Its integrated and I can run it using 'npm test' via a reference in the package.json file.
"scripts": {
"test": "lab -T ./node_modules/lab-babel -I __core-js_shared__"
}
...
//from the cmd line
npm test
This is working fine - although I am using es6 syntax in the test:
import Server from '../../src/server.js';
import Code from 'code';
import Lab from 'lab';
I want to be able to run the tests from gulp. I am using 'gulp-lab'. It starts to run but then throws an error.
SyntaxError: Unexpected reserved word
Its pointing to the use of import - which I get as its es6. So I tried to pipe the test js through babel before sending it to lab (see below). Unfortunately I get the same error.
Here is the relevant section of my gulp file - any suggestions?
import gulp from 'gulp';
import babel from 'gulp-babel';
import lab from 'gulp-lab';
gulp.task('test', function () {
return gulp.src('test/**/*.js')
.pipe(babel())
.pipe(lab());
});
I can post the rest of the gulp file if it would be useful to see how the build works.
Here is my .babelrc file:
//use es2015 preset to convert es6 js to es5 equivalent
{
"presets": [ "es2015" ],
'plugins': [
'transform-es2015-template-literals',
'transform-es2015-block-scoping'
]
}

Serverless Framework with Node MySQL: PROTOCOL_INCORRECT_PACKET_SEQUENCE error

I'm having difficulties implementing a simple query on a AWS Lambda NodeJS (with Serverless Framework). Running it locally works, but when I upload it to AWS and then try to run it using the API Gateway endpoint, I get this error:
{
"code": "PROTOCOL_INCORRECT_PACKET_SEQUENCE",
"fatal": true
}
I can't find any information on Google, StackOverflow or GitHub about this error, and I can't figure out what I'm doing wrong.
This is what I'm trying.
var mysql = require('mysql');
var connection = mysql.createConnection({
host : '',
user : '',
password : '',
database : ''
});
function getLists (client_id,api_key,callback){
connection.query("SELECT * FROM list WHERE client_id = ?",
[client_id],function(error, results){
connection.end();
callback(error,results);
}
)};
module.exports.run = function(event, context, cb) {
getLists(event.x_mail_list_client_id,'',function(error,results){
if(error){
return cb(null,error);
}
return cb(null,results);
});
};
In general the problem you encounter is the disability of the serverless-optimizer-plugin to handle dynamically loaded NPM modules or globals correctly (e.g. when using the mysql NPM package). So you have to exclude it from optimization.
The solution heavily depends on the serverless version and the Node version you use, so I will list the different solutions below:
Severless v4 + Node v4:
Set the excludes in your s-component.json as follows:
"custom": {
"optimize": {
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql"
]
}
}
Serverless v5 + Node v4:
Components have been obsoleted and removed in this serverless version favoring functions instead. So apply the optimizer configuration directly to your s-function.json configuration files.
Node v5:
The NPM executable included with Node v5 internally does dependency optimization and dependency module flattening. This is not yet really compatible with the current serverless-optimizer-plugin. The solution here is to add the dependencies that are already optimized by NPM as proposed by #Masatsugu Hosoi in his answer above like this
"custom": {
"optimize": {
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql",
"node_modules/bignumber.js",
"node_modules/readable-stream",
"node_modules/isarray",
"node_modules/core-util-is",
"node_modules/inherits",
"node_modules/string_decoder"
]
}
}
edit awsm.json.
"exclude": [
"aws-sdk",
"mysql"
],
"includePaths": [
"node_modules/mysql",
"node_modules/bignumber.js",
"node_modules/readable-stream",
"node_modules/isarray",
"node_modules/core-util-is",
"node_modules/inherits",
"node_modules/string_decoder"
]
https://github.com/felixge/node-mysql/issues/1249
For any coming in the future
what worked for me to add the following in the webpack.config.js file
optimization: {
minimize: false
}
Mysql does not seem to like the minification
I just had this exactly same problem.
The problem is with the browserify and the mysql module. Unfortunately I couldn't find a real solution.
By reading the code the browserify is the only available option as builder.
https://github.com/jaws-framework/JAWS/blob/master/lib/commands/deploy_lambda.js
You can set the 'builder' as false. This will simply zip all your files before sending them to Amazon.
Unfortunately (again) just doing this will not work. For some reason all files are inside a 'node_module' folder to work you must take the files out before upload the package.
Still, all this is manual...
edit: There is already an open issue about this last part:
https://github.com/jaws-framework/JAWS/issues/239