简体   繁体   中英

Duplicated constants between Javascript and server-side code

In my project, I have some of the same variables defined in my JavaScript code as on my server (written in a different language). I have comments that when one side is changed, the other should change as well. This feels like a clumsy way to share these variables.

Is there a standard approach to sharing variables between the JavaScript scripts and the back-end of my website?

Some options I've thought of:

  1. Use a shared constants source file, if you're lucky and the syntax for both languages is compatible.
  2. Dynamically generate a constants file for one of the languages based on the other, as part of the build process.
  3. Generate all JavaScript through a templating language.
  4. Put shared constants inline in the HTML, rather than putting them in JavaScript file.

I assume what you're after is single page applications. You can change your backend to be restful, and whenever something needs to be changed, your Javascript can both update itself and inform backend about it.

Have a look at popular javascript frameworks like AngularJS and see how single page applications are being developed. First few tutorials should get you going.

No, you will not be sharing variables directly. You will be sharing what value your variables contain. When one is changed, you will tell your application to update the other.

For example, let's say you have backend which outputs users in JSON format.

{
    "users": [
        {
            "firstName": "John",
            "lastName": "Doe"
        },
        {
            "firstName": "Anna",
            "lastName": "Smith"
        },
        {
            "firstName": "Peter",
            "lastName": "Jones"
        }
    ]
}

You will first initialize this information on a javascript variable. Then, each time an user is (let's say deleted), you need to both remove user from this variable and also inform backend about it, so they will be in sync.

I would like to give you more information about it but I'm sure the very first tutorials of AngularJS will clear many things in your mind.

I wrote a Python tool called Reconstant to solve this exact problem.

Here is an example input file test.yaml :

constants:
- name: SOME_CONSTANT
  value: "this is a constant string"
- name: OTHER_CONSTANT
  value: 42

enums:
- name: SomeEnum
  values:
    - A
    - B
    - C
- name: OtherEnum
  values:
    - FOO
    - BAR

outputs:
  python:
    path: autogenerated_constants.py
  javascript:
    path: autogenerated_constants.js
  c:
    path: autogenerated_constants.h

Now you run reconstant test.yaml and the following output files are generated:

autogenerated_constants.py
# autogenerated by reconstant - do not edit!
from enum import Enum

# constants
SOME_CONSTANT = "this is a constant string"
OTHER_CONSTANT = 42

# enums
class SomeEnum(Enum):
    A = 0
    B = 1
    C = 2

class OtherEnum(Enum):
    FOO = 0
    BAR = 1
autogenerated_constants.js
// autogenerated by reconstant - do not edit!

// constants
export const SOME_CONSTANT = "this is a constant string"
export const OTHER_CONSTANT = 42

// enums
export const SomeEnum = {
    A : 0,
    B : 1,
    C : 2,
}
export const OtherEnum = {
    FOO : 0,
    BAR : 1,
}
autogenerated_constants.h
// autogenerated by reconstant - do not edit!
#ifndef AUTOGENERATED_CONSTANTS_H
#define AUTOGENERATED_CONSTANTS_H

// constants
const char* SOME_CONSTANT = "this is a constant string";
const int OTHER_CONSTANT = 42;

// enums
typedef enum { A, B, C } SomeEnum;
typedef enum { FOO, BAR } OtherEnum;

#endif /* AUTOGENERATED_CONSTANTS_H */

This doesn't yet support all the languages you mentioned, but it is very easy to add support for a new language. The Python output shown above is implemented in nine lines of code and the C output (which is the most complicated) is implemented in thirty lines of code.

option1 environment variables

This would depend on your exact setup, but I would use environment variables for those constants as most languages and build tools already support it.

Then have a .env file that gets pulled from a common location I both projects.

option2 config api endpoint

Another option is to have an api endpoint serving those constants and either use them for the front-end at build time, or even at run-time depending I the specifics of your use case

Integration tests can be a great tool to solve this problem.

Create a test suite which hits your API and compares the returned object & variables with the objects/variables defined in your JavaScript. You can create this API endpoint with some reflection magic and include metadata to simplify this comparison or compare other information, too.

Then have your integration test suite run on a continuous integration server, maybe triggered by a commit both on the JS or the API/server side, and automatically inform you of test failure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM