Once more: Django 1.10.
New middleware style. In the documentation we have:
https://docs.djangoproject.com/en/1.10/releases/1.10/#new-style-middleware
https://docs.djangoproject.com/en/1.10/topics/http/middleware/#upgrading-pre-django-1-10-style-middleware
I need Django Debug Toolbar. Release 1.5 is compatible with Django 1.10.
This is installation documentation: https://django-debug-toolbar.readthedocs.io/en/stable/installation.html
The Django Debug Toolbar needs:
MIDDLEWARE_CLASSES = [
# ...
'debug_toolbar.middleware.DebugToolbarMiddleware',
# ...
]
Well, I tried to add 'debug_toolbar.middleware.DebugToolbarMiddleware' to existing MIDDLEWARE. No success (the server doesn't run, some exceptions are risen).
Then I just renamed MIDDLEWARE into MIDDLEWARE_CLASSES.
Working.
What troubles me: I can't find in the documentation that MIDDLEWARE_CLASSES is supported. But everything works.
Could you give me some piece of advice: is it Ok to use MIDDLEWARE_CLASSES settings or not? And where to read about this.
Since Django 1.10 introduced new middleware style, existing middlewares should be updated.
https://github.com/jazzband/django-debug-toolbar/issues/853
Your files should have content similar to the following:
prj/prj/settings.py
# { django-debug-toolbar
DEBUG_TOOLBAR_PATCH_SETTINGS = False
INTERNAL_IPS = ['127.0.0.1', ]
if DEBUG:
# MIDDLEWARE += ['debug_toolbar.middleware.DebugToolbarMiddleware',]
MIDDLEWARE += ['test_app.crutch.AdaptedTo110DebugMiddleware',]
INSTALLED_APPS += ['debug_toolbar',]
# } django-debug-toolbar
prj/prj/urls.py
from django.conf import settings # for django-debug-toolbar
# { django-debug-toolbar
if settings.DEBUG:
import debug_toolbar
urlpatterns += [
url(r'^__debug__/', include(debug_toolbar.urls)),
]
# } django-debug-toolbar
prj/test_app/crutch.py
# a crutch for the debugger
from django.utils.deprecation import MiddlewareMixin
from debug_toolbar.middleware import DebugToolbarMiddleware
class AdaptedTo110DebugMiddleware(MiddlewareMixin, DebugToolbarMiddleware):
pass
Related
import nextJest from 'next/jest'
const createJestConfig = nextJest({
dir: './',
})
// Add any custom config to be passed to Jest
const customJestConfig = {
setupFilesAfterEnv: ['<rootDir>/setupTests.js'],
moduleDirectories: ['node_modules', '<rootDir>/'],
testEnvironment: 'jest-environment-jsdom',
modulePathIgnorePatterns: ['./cypress'],
// testMatch: ['<rootDir>/**/*.test.js', '<rootDir>/**/*.test.jsx'],
}
module.exports = createJestConfig(customJestConfig)
In my project, we use Nextjs application with both Cypress and Jest. The latest jest.config.ts which is recommended is shown above.
If you are now owned this problem. you can maybe try to check your modulePathIgnorePatterns.
I added a ./ to ['cypress'], then it works well. So, I think maybe it just cann't recognize the path.
I'm trying to setup my nextjs app to use runtime configurations. Basically, I have an endpoint url that needs to be available trough docker env vars.
I configured following these docs but it isn't working. My app still using default values from .env file. Could anyone help to understand what I missed or did wrong?
Thanks!
docs:
https://nextjs.org/docs/api-reference/next.config.js/runtime-configuration
https://nextjs.org/docs/advanced-features/custom-app
steps:
1- added to my next.config.js
publicRuntimeConfig: {
NEXT_PUBLIC_BACKEND_HOST: process.env.NEXT_PUBLIC_BACKEND_HOST,
},
2- retrieved config in my pages
const { publicRuntimeConfig } = getConfig()
const baseURL = publicRuntimeConfig.NEXT_PUBLIC_BACKEND_HOST
3- created a custom app to setup getInitialProps
Runtime configuration won't be available to any page (or component in a page) without getInitialProps.
import App from 'next/app'
function MyApp({ Component, pageProps }) {
return <Component {...pageProps} />
}
MyApp.getInitialProps = async (appContext) => {
const appProps = await App.getInitialProps(appContext);
return { ...appProps }
}
export default MyApp
Everything seems fine in your code, tested in a fresh project and everything worked correctly. Therefore I think the issue is that you don't actually have NEXT_PUBLIC_BACKEND_HOST env var set when you're running next start. Btw, you don't need to use the NEXT_PUBLIC prefix in this kind of usage. If you want build time args you can use NEXT_PUBLIC_ prefix to have the var be available both client and server side by just using process.env.NEXT_PUBLIC_ anywhere. Note that in that case the value will be inlined at build time, so the env var needs to be present during build.
My Main goal is to create an Electron App (Windows) that locally stores data in an SQLite Database. And because of type safety I choose to use the Prisma framework instead of other SQLite Frameworks.
I took this Electron Sample Project and now try to include Prisma. Depending on what I try different problems do arrise.
1. PrismaClient is unable to be run in the Browser
I executed npx prisma generate and then try to execute this function via a button:
import { PrismaClient } from '#prisma/client';
onSqlTestAction(): void {
const prisma = new PrismaClient();
const newTestObject = prisma.testTable.create(
{
data: {
value: "TestValue"
}
}
);
}
When executing this in Electron I get this:
core.js:6456 ERROR Error: PrismaClient is unable to be run in the browser.
In case this error is unexpected for you, please report it in https://github.com/prisma/prisma/issues
at new PrismaClient (index-browser.js:93)
at HomeComponent.onSqlTestAction (home.component.ts:19)
at HomeComponent_Template_button_click_7_listener (template.html:7)
at executeListenerWithErrorHandling (core.js:15281)
at wrapListenerIn_markDirtyAndPreventDefault (core.js:15319)
at HTMLButtonElement.<anonymous> (platform-browser.js:568)
at ZoneDelegate.invokeTask (zone.js:406)
at Object.onInvokeTask (core.js:28666)
at ZoneDelegate.invokeTask (zone.js:405)
at Zone.runTask (zone.js:178)
It somehow seems logical that Prisma cannot run in a browser. But I actually build a native app - with Electron that embeds a Browser. It seems to be a loophole.
2. BREAKING CHANGE: webpack < 5 used to include polyfills
So i found this Question: How to use Prisma with Electron
Seemed to be exactly what I looked for. But the error message is different (Debian binaries were not found).
The solution provided is to generate the prisma artifacts into the src folder instead of node_modules - and this leads to 19 polyfills errors. One for example:
./src/database/generated/index.js:20:11-26 - Error: Module not found: Error: Can't resolve 'path' in '[PATH_TO_MY_PROJECT]\src\database\generated'
BREAKING CHANGE: webpack < 5 used to include polyfills for node.js core modules by default.
This is no longer the case. Verify if you need this module and configure a polyfill for it.
If you want to include a polyfill, you need to:
- add a fallback 'resolve.fallback: { "path": require.resolve("path-browserify") }'
- install 'path-browserify'
If you don't want to include a polyfill, you can use an empty module like this:
resolve.fallback: { "path": false }
And this repeats with 18 other modules. Since the error message to begin with was different I also doubt that this is the way to go.
I finally figured this out. What I needed to understand was, that all Electron apps consist of 2 parts: The Frontend Webapp (running in embedded Chromium) and a Node backend server. Those 2 parts are called IPC Main and IPC Renderer and they can communicate with each other. And since Prisma can only run on the main process which is the backend I had to send my SQL actions to the Electron backend and execute them there.
My minimal example
In the frontend (I use Angular)
// This refers to the node_modules folder of the Electron Backend, the folder where the main.ts file is located.
// I just use this import so that I can use the prisma generated classes for type safety.
import { TestTable } from '../../../app/node_modules/.prisma/client';
// Button action
onSqlTestAction(): void {
this.electronService.ipcRenderer.invoke("prisma-channel", 'Test input').then((value) => {
const testObject: TestTable = JSON.parse(value);
console.log(testObject);
});
The sample project I used already had this service to provide the IPC Renderer:
#Injectable({
providedIn: 'root'
})
export class ElectronService {
ipcRenderer: typeof ipcRenderer;
webFrame: typeof webFrame;
remote: typeof remote;
childProcess: typeof childProcess;
fs: typeof fs;
get isElectron(): boolean {
return !!(window && window.process && window.process.type);
}
constructor() {
// Conditional imports
if (this.isElectron) {
this.ipcRenderer = window.require('electron').ipcRenderer;
this.webFrame = window.require('electron').webFrame;
this.childProcess = window.require('child_process');
this.fs = window.require('fs');
// If you want to use a NodeJS 3rd party deps in Renderer process (like #electron/remote),
// it must be declared in dependencies of both package.json (in root and app folders)
// If you want to use remote object in renderer process, please set enableRemoteModule to true in main.ts
this.remote = window.require('#electron/remote');
}
}
And then in the Electron backend I first added "#prisma/client": "^3.0.1" to the package.json (for the Electron backend not the frontend). Then I added to the main.ts this function to handle the requests from the renderer:
// main.ts
ipcMain.handle("prisma-channel", async (event, args) => {
const prisma = new PrismaClient();
await prisma.testTable.create(
{
data: {
value: args
}
}
);
const readValue = await prisma.testTable.findMany();
return JSON.stringify(readValue);
})
This way of simply adding the IPC Main handler in the main.ts file of course is a big code smell but usefull as minimal example. I think I will move on with the achitecture concept presented in this article.
In some popular NodeJS libraries, e.g. ssh2 or node-pty, there is natively compiled code as part of the library.
Creating the project with
vue create my-project
vue add electron-builder
yarn add ssh2
then importing and using ssh2's Client in the background process results in following errors during
electron:build
ERROR Failed to compile with 1 errors 5:29:10 PM
error in ./node_modules/cpu-features/build/Release/cpufeatures.node
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type, currently no loaders are configured to process this file. See https://webpack.js.org/concepts#loaders
(Source code omitted for this binary file)
# ./node_modules/cpu-features/lib/index.js 1:16-60
# ./node_modules/ssh2/lib/protocol/constants.js
# ./node_modules/ssh2/lib/client.js
# ./node_modules/ssh2/lib/index.js
...
This error occurs with many other libs or transitive dependencies and the reason for it is absence of native-ext-loader on Webpack chain. I understand why it is not included by default, and I would like to see what is the best way to add it.
One solution I found is this:
Add yarn add -D native-ext-loader (my version is 2.3.0 and electron is at 13.x)
Adjust vue.config.js and add the chainWebpackMainProcess like this:
const path = require('path')
module.exports = {
pluginOptions: {
electronBuilder: {
builderOptions: {
// options placed here will be merged with default
mac: {
target: 'dmg',
icon: 'build/icon.icns',
asar: true
}
},
preload: 'src/preload.ts',
chainWebpackMainProcess(config) {
config.module
.rule("node")
.test(/\.node$/)
.use("native-ext-loader")
.loader("native-ext-loader")
.options(
process.env.NODE_ENV === "development"
? {
rewritePath: path.resolve(__dirname, "native"),
}
: {}
)
}
}
}
}
Both, electron:build and electron:serve are now working and ssh2 client is happily delivering the stdout to renderer via ipcMain. Not sure it is the most elegant way of solving it, though.
How do I set key in a local.sbt in such a way that every subproject finds it ?
I'm trying to use Coursier plugin in a multi project, but since I'm testing it, I'm trying not to check it in in our git repo.
So I put it in my project/local.sbt and I was trying to set coursierUseSbtCredentials := true in a local.sbt.
This has no visible effect.
The authenticated nexus is defined in the commonSettings val in my build.sbt
val commonSettings = Seq(
...
resolvers += "my-nexus" at "http://blah",
credentials += ...
)
which every sub-project uses with .settings(commonSettings) (as per best-practices guide)
If I put coursierUseSbtCredentials := true in commonSettings it does work, but then I'd have to add it in my build.sbt, which I would rather not do.
How do I set this key so that every subproject can see it and in such a way that it is external to the build.sbt file ? (e.g. local.sbt ?)
Create a local plugin at project/SetupCoursierPlugin.scala:
import sbt._
import coursier.CoursierPlugin, CoursierPlugin.autoImport._
object SetupCoursierPlugin extends AutoPlugin {
override def requires = CoursierPlugin
override def trigger = allRequirements
override def projectSettings = Seq(
coursierUseSbtCredentials := true
)
}