Managing Dependencies in Multi-Package JavaScript Projects Quiz

Explore essential concepts for handling dependencies across multi-package JavaScript projects, focusing on dependency types, versioning, linking, resolution, and common workflows. Strengthen your frontend development skills by understanding best practices for maintaining consistency and efficiency in monorepo settings.

  1. Types of Dependencies

    In a multi-package JavaScript project, which type of dependency should be used for packages required only during development, such as testing libraries?

    1. devDependencies
    2. peerDependencies
    3. mainDependencies
    4. bundleDependencies

    Explanation: devDependencies are specifically meant for packages only needed during development, like linters or test frameworks. mainDependencies is not a recognized term in dependency management. peerDependencies define a package requirement that must be provided by the consumer, not installed automatically. bundleDependencies are used for bundling dependencies directly, which is uncommon outside some specific scenarios.

  2. Dependency Declaration

    Where are dependencies typically declared for each package in a multi-package JavaScript project?

    1. package.json
    2. dependency.txt
    3. manifest.js
    4. package.lock

    Explanation: The package.json file is the standard location for declaring dependencies in JavaScript projects. dependency.txt and manifest.js are not valid or standard files for this purpose. package.lock is used for locking dependency versions, not for their declaration.

  3. Workspace Root Dependencies

    In a monorepo with multiple packages, what is the effect of installing a dependency at the root level instead of within a specific package?

    1. It makes the dependency available to all packages
    2. It restricts the dependency to just one package
    3. It prevents the dependency from being installed
    4. It causes version conflicts with all packages

    Explanation: Installing a dependency at the root of a monorepo generally makes it accessible to all contained packages, simplifying shared usage. Restricting to just one package requires installing locally within that package. The installation does not block the dependency from being installed or inherently cause conflicts, although incorrect versioning could lead to issues.

  4. Linking Local Packages

    Which method is often used to enable one local package in a multi-package project to use code from another local package before publishing?

    1. Symlinking
    2. Cloning
    3. Forking
    4. Bundling

    Explanation: Symlinking allows local packages to reference and use each other's code as though they were installed dependencies. Cloning and forking deal with source control, not dependency management. Bundling involves packaging code for deployment, not connecting packages locally.

  5. Resolving Version Conflicts

    If two packages in your multi-package JavaScript project depend on different versions of the same library, what can occur during dependency resolution?

    1. Multiple versions may be installed
    2. The higher version always overwrites the lower
    3. No versions are installed
    4. Only the lower version is kept

    Explanation: When dependency versions differ, multiple versions may be installed to satisfy each package's requirements. The higher or lower version does not universally replace the other; resolution depends on package manager rules. Not installing any versions is not typical in this scenario.

  6. Peer Dependencies Purpose

    Why would you specify a package as a peer dependency instead of a regular dependency in a reusable component package?

    1. To require the consumer to provide it
    2. To hide it from downstream packages
    3. To force bundling during build
    4. To convert it into a devDependency

    Explanation: Peer dependencies signal that the consuming project must install the package, ensuring compatibility in the host environment. Hiding or bundling is unrelated to peer dependencies, and converting to a devDependency changes its installation context.

  7. Updating Dependencies

    What is the recommended practice before updating a shared dependency in a multi-package project?

    1. Test the update in all affected packages
    2. Update every package automatically
    3. Remove the dependency and reinstall
    4. Ignore version constraints

    Explanation: Testing updates across all relevant packages helps ensure stability and compatibility. Automatically updating every package or reinstalling without caution can introduce bugs. Ignoring version constraints is risky and may break functionality.

  8. Transitive Dependencies

    What are transitive dependencies in the context of a multi-package JavaScript project?

    1. Packages indirectly required by other dependencies
    2. Main dependencies installed directly
    3. Dev dependencies only
    4. Packages excluded from installation

    Explanation: Transitive dependencies are libraries that your project's dependencies pull in, even if you didn't specify them directly. Main dependencies are those you list directly. Dev dependencies are only for development, and excluded packages are not part of this concept.

  9. Lockfile Usage

    What is the main function of a lockfile in a multi-package environment?

    1. To maintain consistent dependency versions
    2. To restrict package publication
    3. To increase build speed
    4. To generate API documentation

    Explanation: A lockfile ensures all contributors install the exact same package versions, boosting reliability. It does not restrict publication, directly speed up builds, or generate documentation, which require different tools.

  10. Hoisting Dependencies

    In a monorepo, what does 'hoisting' dependencies mean?

    1. Moving shared dependencies to the root
    2. Separating modules into different folders
    3. Deleting unused packages
    4. Renaming dependency files

    Explanation: Hoisting refers to moving shared dependencies to the root node_modules to avoid duplication. Separating folders and deleting packages are unrelated to hoisting. Renaming files does not impact dependency resolution.

  11. Dependency Cycles

    Why should you avoid creating cycles between packages (circular dependencies) in a multi-package JavaScript project?

    1. They can cause import errors and unpredictable behavior
    2. They improve performance
    3. They are required for tree-shaking
    4. They reduce duplication automatically

    Explanation: Circular dependencies can lead to import errors, initialization bugs, or unpredictable behavior. They don't help with performance, are not required for tree-shaking, and do not inherently reduce duplication.

  12. Version Range Specifiers

    If you see a dependency version specified as '^1.0.0' in package.json, what does this mean?

    1. Updates are allowed for backward-compatible minor and patch versions
    2. Only exactly version 1.0.0 is allowed
    3. Only major updates are allowed
    4. No updates are permitted

    Explanation: The caret symbol (^) allows updates for minor and patch versions, ensuring compatibility. An exact version is indicated without any symbol. Allowing only major updates is not the role of ^, and restricting all updates is also incorrect.

  13. Workspace Protocol

    In a monorepo, using 'workspace:' as a version specifier means what for dependency installation?

    1. It links a local workspace package as a dependency
    2. It fetches the package from a remote registry
    3. It locks the dependency at the root only
    4. It removes the need for a lockfile

    Explanation: The 'workspace:' protocol tells the package manager to link a dependency from another local workspace package. It does not fetch from a remote registry. The lockfile is still needed, and root locking is not directly tied to this protocol.

  14. Duplicated Dependencies

    What is a potential problem if multiple different versions of the same dependency are installed in a multi-package project?

    1. Increased bundle size and possible runtime errors
    2. Faster development builds
    3. Improved dependency resolution
    4. Higher compatibility with all packages

    Explanation: Having multiple versions can increase bundle size and cause conflicts if packages expect different API behavior. It does not speed up builds, improve resolution, or automatically increase compatibility.

  15. Installing All Package Dependencies

    In a multi-package JavaScript project, what is a common way to install all dependencies for every package at once?

    1. Run the package manager at the root directory
    2. Install dependencies individually in each package
    3. Use only the package-lock file
    4. Edit node_modules folders by hand

    Explanation: Running installation from the root processes all workspace packages, installing each package’s dependencies. Doing installs individually is more time-consuming. Editing node_modules by hand is error-prone, and the lockfile alone doesn't install dependencies.

  16. Package Publishing Setup

    Before publishing a package from a multi-package project, what is a necessary step regarding its dependencies?

    1. Ensure all required dependencies are correctly listed
    2. Delete all dependencies from package.json
    3. List devDependencies as peerDependencies
    4. Install dependencies in the root only

    Explanation: Correctly listing all required dependencies ensures the package functions for users. Deleting dependencies or improperly moving them can break the package. Root installations don't transfer to users unless dependencies are specified per package.

  17. Reducing Redundant Dependencies

    What is one benefit of using shared dependencies across packages in a multi-package project?

    1. Reduces duplication and saves storage space
    2. Slows down the build process
    3. Increases code complexity
    4. Forces each package to use a different version

    Explanation: Shared dependencies avoid installing multiple copies, which reduces storage use and may improve performance. It does not slow builds or increase complexity, and it actually encourages using the same version for consistency.

  18. Dependency Tree Inspection

    Why might you inspect the dependency tree of a multi-package JavaScript project?

    1. To identify duplicate or conflicting dependencies
    2. To delete cached modules
    3. To bypass security warnings
    4. To start the development server

    Explanation: Inspecting the dependency tree helps spot and resolve duplicates or version conflicts. It is unrelated to deleting caches, skipping warnings, or serving the application.

  19. Local vs. External Dependencies

    In a multi-package project, what distinguishes a local package dependency from an external one?

    1. Local is another package in the same repo; external comes from a package registry
    2. Local requires internet access; external is always offline
    3. Local is only for testing; external is always for production
    4. Local is always installed globally; external is always installed locally

    Explanation: Local dependencies are packages managed within the same repository and can be linked directly, whereas external dependencies are fetched from registries. Local does not require internet, nor is it only for testing. Installation location (global or local) is unrelated.

  20. Locking Exact Versions

    Which file is most responsible for ensuring that all collaborators install the exact same dependency versions in a multi-package project?

    1. Lockfile (such as package-lock.json)
    2. Readme file
    3. Gitignore file
    4. Manifest.js file

    Explanation: The lockfile records the precise versions installed, so everyone on the project uses compatible dependencies. The Readme offers guidance, gitignore affects version control, and manifest.js is not a standard file.

  21. Dependency Management Automation

    What is one benefit of using automation tools for managing dependencies in a multi-package JavaScript project?

    1. Helps keep dependencies up to date and consistent
    2. Forces manual updates for every package
    3. Prevents new package installation
    4. Automatically removes all dependencies on error

    Explanation: Automation tools offer streamlined dependency management, reducing manual effort and errors. They don't force manual updates, block new packages, or remove dependencies without reason.