How do I include a JavaScript library in Yii2 using Composer?

After successfully setting up a basic app following the steps outlined in this installation guide for Yii, I encountered a new challenge. The requirement now is to utilize q.js, which is available as an npm package. However, I am unsure of how to incorporate it using composer. Although alternatives like using a CDN or manual download are possible, my preference is to utilize composer. How can I achieve this?

In my composer.json file, I included the following:

"require": {
    "php": ">=5.4.0",
    "yiisoft/yii2": ">=2.0.4",
    "yiisoft/yii2-bootstrap": "*",
    "yiisoft/yii2-swiftmailer": "*",
    "npm-asset/q": "~1.4"               <------
},

Upon running composer.phar update, I encountered the error:

Your requirements could not be resolved to an installable set of packages.

    Problem 1
    - The requested package npm-asset/q could not be found in any version, 
      there may be a typo in the package name.

This raises the question of whether my approach is incorrect.

I am also seeking guidance on how to add JavaScript libraries to the project. While I understand that adding it to an Asset is necessary at a later stage, my current hurdle is obtaining the JS file initially.

* Is 'hosted' the appropriate term to use in this context?

Answer №1

If you're looking for a simple way to include npm or bower packages in your composer.json file, consider using the convenient asset-packagist service:

  1. Start by removing the fxp/composer-asset-plugin:

    composer global remove fxp/composer-asset-plugin
    
  2. Next, add the asset-packagist repository to your composer.json file:

    "repositories": [
        {
            "type": "composer",
            "url": "https://asset-packagist.org"
        }
    ]
    

Once that's done, you can easily require npm packages with the prefix npm-asset/ and bower packages with the prefix bower-asset/ in your composer.json file:

"require": {
    "bower-asset/bootstrap": "^3.3",
    "npm-asset/jquery": "^2.2"
}

By following these steps, you eliminate the need for a global plugin and enjoy quicker composer updates.

Answer №2

The most effective approach is to modify the asset/AppAsset.php file as follows:

class AppAsset extends AssetBundle
{
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $js = [
        'js\custom_file.js',
    ];
    public $depends = [
        'yii\web\YiiAsset',
        'yii\bootstrap\BootstrapAsset',
    ];
}

Create a js folder within your web directory and place your custom JavaScript file in it.

To include the JavaScript file, use the following code:

$this->registerJsFile(Yii::$app->request->baseUrl.'/js/custom_file.js');

Answer №3

Perhaps the author's advice is a bit delayed, but it could still be beneficial for others.

Using Composer

If your library does not have a composer setup (meaning there is no composer.json file in its root with necessary information for packagist.org), including it via composer can be challenging.

On the other hand, including CDN libraries is straightforward and best done using AssetBundle, like this:

<?
namespace frontend\assets;

use yii\web\AssetBundle;
// Main frontend application asset bundle
class AppAsset extends AssetBundle {
    public $basePath = '@webroot';
    public $baseUrl = '@web';
    public $css = [
        '//fonts.googleapis.com/css?family=Open+Sans:400,600&amp;subset=cyrillic,cyrillic-ext',
        '//cdn.jsdelivr.net/npm/<a href="/cdn-cgi/l/email-protection" class="__cf_email__" data-cfemail="8afaf8effefef3a7e9e2efe9e1e8e5f2cab9a4ba">[email protected]</a>/dist/pretty-checkbox.min.css'
    ];
    public $js = [];
    public $depends = [
        'yii\web\YiiAsset',
    ];
}

Linking vendor-based JS

Linking to JS libraries installed through composer may seem complicated because the vendor folder is not web-accessible, but it's actually quite simple with Yii2.

Yii2's AssetBundle offers a sourcePath option that allows you to link to a directory that isn't publicly accessible (like vendor).

Yii will handle publishing the included files to the @web/assets/ folder and linking to them at runtime.

Here's an example using jquery.cookie:

<?
namespace frontend\assets;

use yii\web\AssetBundle;
// Class JqueryCookieAsset
class JqueryCookieAsset extends AssetBundle {
    public $sourcePath = '@vendor/components/jquery-cookie';
    
    public $js = [
        'jquery.cookie.js'
    ];
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Buttoned Up: The Troubling Tale of jQuery and

Seems like this question might be a duplicate, but I'm not bothered. Despite searching on Google, I haven't found a solution. What could be the mistake here? $(document).ready(function() { $("#foo").click(function() { $.ajax({ type ...

The JSON object array is not empty, but it is unable to be iterated using a foreach loop, displaying a

Exploring a library of books from a Firestore collection in the create() method. The book data is stored in an array called checkout which is initialized in the data() method. export default { name: "checkout-history", data() { return { che ...

Troubleshooting Firefox in Python Selenium: When using driver.execute_script to delete text characters using JQuery, encountering "SecurityError: The operation is insecure" error

Currently working with Selenium 3.141.0 using Python and Firefox 88.0 with geckodriver 0.29.1. In the past, I successfully used the following JavaScript code to remove unwanted characters (like ®) from web pages, as referenced in this answer: driver.exec ...

What are some strategies for handling data after it has been retrieved using Axios?

In my current project, I am working with MySQL database and fetching data using Axios and a useEffect hook. Once the data is retrieved, I pass it to a component as a prop. Here's how: const Component = () => { //Database URL const urlProxy = &q ...

A guide on seamlessly transitioning from a mobile website to the corresponding native app

I am currently working on a mobile website project. This website is built using basic HTML and is accessed through a URL on a web browser, not as a native app or through PhoneGap. The client has requested links to their Facebook, Pinterest, YouTube, Twitt ...

Utilize focusout and onclick events on multiple components at the same time

Currently, I am in the process of coding an Autocomplete feature from scratch in Vue, but I am encountering a challenge when it comes to selecting an option from the dropdown menu. I have set it up so that the dropdown is shown when the input is clicked ...

Avoid losing focus on href="#" (preventing the page from scrolling back up to the top)

Is there a way to prevent an empty href link from causing the page to scroll up when clicked? For example, if I have: <a href="#">Hello world</a> And this "Hello world" link is in the middle of the page. When clicked, the URL would look like ...

Insert information into the window before it loads

Exploring the process of opening new windows using JavaScript. var myWindow = window.open(); myWindow.document.write('html'); Is it feasible to inject content into the document before the window fully loads? I aim to include a complete HTML str ...

Identify the NPM packages utilized by an active node.js program

Is there a method to identify the dependencies of a running node.js application without directly accessing the package.json file at the project root? Perhaps node stores this information in a variable within the global namespace? ...

items within the grid container are positioned without being constrained to rows and columns

After using the Container element, I noticed that all my grid items are displaying in columns instead of rows. How can I correct this layout issue? https://i.stack.imgur.com/9BjOA.png Click here to access the project link. ...

Encountering JSON error when invoking multiple functions

Encountering JSON Error when calling multiple functions Error - Uncaught SyntaxError: Unexpected token ' in JSON at position 0 I've been attempting to call multiple functions in jQuery but keep getting an error. I've tried various soluti ...

Passport.js implementation in a Next.js application does not persist the user's login state when navigating between routes

I'm currently utilizing passport.js with the local-strategy for authentication in my next.js application. Data store requests and authentication are functioning properly. However, I need access to the req.user in another route to retrieve the users._ ...

I am unable to generate an Angular file

PS D:\AngularCalismalar> ng new intro Node.js version v17.1.0 was detected. It is recommended not to use odd numbered Node.js versions for production as they will not enter LTS status. For more information, visit https://nodejs.org/en/about/relea ...

Retrieve data from REST call to populate Material dropdown menu

I am looking to dynamically populate a dropdown menu with data retrieved from a Rest API. I attempted the following code: <Select id="country-helper"> {array.map((element) => ( <MenuItem value={element.code}>{element.country}& ...

Tips for incorporating VueJS 2 global components within single file components

As I attempt to utilize a globally registered component (using Vue.component) within a single file component, I consistently encounter the following warning: vue.common.js:2611[Vue warn]: Unknown custom element: <my-component> - did you register the ...

Unfolding the potential of variables in JSON.stringify with Node.js

I am currently developing a node.js API for my app, which includes a simple TCP server that accepts NDJSON (newline delimited JSON). However, I have encountered an issue with the JSON stringify method. The problem arises when I attempt to expand all variab ...

<use> - SVG: Circles with different stroke properties

Why is the stroke of both <use> elements being ignored here? The stroke color of <circle> is set to blue, which is also appearing on both <use> elements. Why? I am trying to set different stroke colors for all three of these elements, bu ...

Utilizing Angular 2+ with the [innerHTML] property to incorporate HTML with added style attributes

I am currently utilizing Angular 2+ [innerHTML] input for inserting HTML formatting that includes style tags. Within my template, the code looks like this: <span [innerHTML]="someVar"></span> In the component file, I have defined: someVar = ...

Mastering form reset functionality using jquery

When attempting to register, an error is generated if any field is left blank in the form (from PHP). The input fields that have been filled out are retained using Smarty: {if isset($smarty.post.registratie.naam)} value="{$smarty.post.registratie.naam}"{el ...

Refresh a page in AngularJS with only a single click

I am currently working with angularjs and I am trying to figure out how to refresh the page only once when it loads. Here is what I have attempted so far: <script> app.cp.register('userProfileController', function ($window) { debugger; ...