Keywords: Create-React-App | package.json | version access
Abstract: This article addresses the common challenge of accessing version numbers from package.json files in Create-React-App projects. Due to Create-React-App's default restriction on importing files from outside the src directory, direct imports of package.json result in module not found errors. The article analyzes two primary solutions: using environment variables and creating symbolic links. The environment variable approach injects npm package information into the React application through .env configuration, while the symbolic link method creates a link within the src directory to bypass import restrictions. Both methods have their advantages and limitations, with environment variables aligning better with Create-React-App's design philosophy and symbolic links offering more direct access. The discussion includes practical considerations and use cases to help developers choose the appropriate method for their specific needs.
In React projects built with Create-React-App, accessing version numbers from package.json files is a common requirement that encounters import restrictions. Create-React-App's default configuration only allows module imports from within the src directory, while package.json typically resides in the project root, causing attempts like import packageJson from './../../package.json' to generate the error: "Module not found: You attempted to import ./../../package.json which falls outside of the project src/ directory."
Environment Variable Solution
A recommended approach involves using environment variables to pass information from package.json. This requires Create-React-App version 1.1.0 or higher. Create or edit the .env file in the project root with the following content:
REACT_APP_VERSION=$npm_package_version
REACT_APP_NAME=$npm_package_name
In React components, the version can then be accessed via process.env.REACT_APP_VERSION. For example, add to index.js:
console.log(`${process.env.REACT_APP_NAME} ${process.env.REACT_APP_VERSION}`)
This method leverages environment variables set by npm during script execution. Note that changes to the .env file require restarting the development server. The advantage is that it maintains project structure integrity and aligns with Create-React-App patterns, though it only provides access to predefined variables.
Symbolic Link Solution
An alternative method creates symbolic links to enable direct access to package.json from within src. Execute these commands from the project root:
cd src
ln -s ../package.json package.alias.json
This creates a symbolic link named package.alias.json in the src directory pointing to the root package.json. After creation, import in React components:
import packageJson from './package.alias.json'
Using the .alias suffix helps distinguish the link from the original file, preventing confusion. This approach provides full access to all fields in package.json but requires additional setup and may cause issues in certain development environments.
Comparison and Selection
The environment variable method is more suitable for scenarios requiring only a few predefined fields like version or app name, offering simplicity and integration with Create-React-App's configuration system. The symbolic link method better serves cases needing access to multiple or dynamic fields from package.json, providing greater flexibility.
In practical applications, such as with CI tools like Jenkins, environment variables may be easier to configure as version information can be automatically injected during builds. Symbolic links might be more practical in development scenarios requiring frequent reads of package.json content.
Considerations
Regardless of the chosen method, consider Create-React-App version compatibility, as earlier versions may not support environment variable injection or symbolic links. In collaborative projects, ensure all developers understand the configuration method to avoid environment inconsistencies.
For projects using React Redux, these methods remain applicable. Version information can be stored in Redux state and shared across components via actions or selectors for unified version management.