I have followed the setup guide on the project page to get composer to install the ckeditor-wordcount-plugin plugin in the libraries folder.
When I require the module, the plugin is put into the vendor folder instead.

What is going wrong? Below is the relevant part of my composer.json file:

{
    ...
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "composer",
            "url": "https://asset-packagist.org"
        }
    ],
    "require": {
        "composer/installers": "^1.4",
        "cweagans/composer-patches": "^1.6",
        "drupal/core": "~8.9.0",
        "drupal/core-composer-scaffold": "^8.9",
        "drupal/core-project-message": "^8.9",
        "drupal/core-vendor-hardening": "^8.9",

        ...

        "drupal/ckwordcount": "^1.1",

        ...

        "drush/drush": "^9.6.2",
        "hirak/prestissimo": "^0.3.7",
        "oomphinc/composer-installers-extender": "^1.1",
        "wikimedia/composer-merge-plugin": "^1.4",
        "zaporylie/composer-drupal-optimizations": "^1.0"
    },
    "conflict": {
        "drupal/drupal": "*"
    },
    "minimum-stability": "dev",
    "prefer-stable": true,
    "extra": {
        "merge-plugin": {
            "include": [
                "http/modules/contrib/webform/composer.libraries.json"
            ]
        },
        "drupal-scaffold": {
            "locations": {
                "web-root": "./http/"
            }
        },
        "enable-patching": true,
        "composer-exit-on-patch-failure": true,
        "installer-paths": {
            "http/core": [ "type:drupal-core" ],
            "http/modules/contrib/{$name}": [ "type:drupal-module" ],
            "http/libraries/{$name}": [ "type:drupal-library", "w8tcha/ckeditor-wordcount-plugin", "type:bower-asset", "type:npm-asset" ]
        },
        "installer-types": [ "bower-asset", "npm-asset" ]
    }
}

Comments

weseze created an issue. See original summary.

weseze’s picture

Issue summary: View changes
jcnventura’s picture

Status: Active » Postponed (maintainer needs more info)

Probably some issue on how you're using composer. Try to rm -rf http/libraries vendor and try to run composer install again.

weseze’s picture

Status: Postponed (maintainer needs more info) » Active

I've tried everything I can think of and it isn't working.
bower assets are working fine, webform libraries are working fine, ...

What extra info can I provide to find the cause of the issue? I see the module doesn't require composer-installers, isn't that necessary?

jcnventura’s picture

Status: Active » Postponed (maintainer needs more info)

No, it isn't because the module is also not setting up the installer-paths.

But yes, your site's root composer file must require composer/installers as yours seems to do. It makes no sense to specify a requirement on this, as the module is not really interested on what installs the w8tcha/ckeditor-wordcount-plugin package in web/libraries/{name} instead of in vendor/{name}.

Honestly, this seems to be a problem on your usage of composer. Try maybe to do the following:

rm -rf composer.lock http/core http/modules/contrib http/libraries
composer update

If the above installs the library in the right place, it means something in your existing composer.lock is the source of the problem.

weseze’s picture

Status: Postponed (maintainer needs more info) » Active

Don't understand why my setup would contain something unusual...
Please see the below simplified example. This still does not install the library in the correct folder. Does this work for you?

{
    "repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        }
    ],
    "require": {
        "composer/installers": "^1.4",
        "drupal/ckwordcount": "^1.1"
    },
    "extra": {
        "installer-paths": {
            "web/libraries/{$name}": [ "type:drupal-library", "w8tcha/ckeditor-wordcount-plugin"  ]
        }
    }
}

Webbeh’s picture

I am able to reproduce this on a standard D8.9 composer install, where adding the project to the "installer-paths" for libraries doesn't seem to queue it for being placed into the defined and working libraries path (as seen by `drupal-ckeditor-libraries-group/notification`).

I wonder if this is the culprit?

https://getcomposer.org/doc/faqs/how-do-i-install-a-package-to-a-custom-...

Note: You cannot use this to change the path of any package. This is only applicable to packages that require composer/installers and use a custom type that it handles.

jcnventura’s picture

Indeed, I can confirm that the minimal setup doesn't work. I believe the reason this works for me is that I include the module as part of our company's profile, and the suceeding requirements manage to fool composer/installers into adding it in the right place.

I might have to fork the original repo to change the type to drupal-library.

weseze’s picture

I've worked around it by adding this piece of code to my composer.json file. Not ideal, but it works.

    "scripts": {
        "post-install-cmd": [
            "cp -R vendor/w8tcha/ckeditor-wordcount-plugin http/libraries/"
        ],
        "post-update-cmd": [
            "cp -R vendor/w8tcha/ckeditor-wordcount-plugin http/libraries/"
        ],
    },

  • jcnventura authored 0baa73d on 8.x-1.x
    Issue #3172165 by jcnventura: Require composer/installers
    
jcnventura’s picture

Status: Active » Postponed

Tried to require composer/installers to try to fool it into installing the plugin, but it still doesn't work right.

I've raised an issue with composer/installers at https://github.com/composer/installers/issues/460

guisharko’s picture

I use this composer.json's configuration to download the librairy, I hope this could help you.

[
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "composer",
            "url": "https://asset-packagist.org"
        },
        {
            "type": "package",
            "package": {
                "name": "w8tchaw8tcha/ckeditor-wordcount-plugin",
                "version": "1.17.6",
                "type": "drupal-library",
                "dist": {
                    "url": "https://download.ckeditor.com/wordcount/releases/wordcount_1.17.6.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "~1.0"
                }
            }
        }
    ],
 

Then composer require w8tchaw8tcha/ckeditor-wordcount-plugin

M_Z’s picture

@weseze:
Thank you for your piece of code in #9, but I had to change your "http/" directory to "web/" (that is the common public directory Name in a Drupal composer installation) and the 2nd last comma must be removed.

So here is my working code that I added to my root composer.json file before the "extra" section:

    "scripts": {
        "post-install-cmd": [
            "cp -R vendor/w8tcha/ckeditor-wordcount-plugin web/libraries/"
        ],
        "post-update-cmd": [
            "cp -R vendor/w8tcha/ckeditor-wordcount-plugin web/libraries/"
        ]
    },

After that a composer require drupal/ckwordcount worked fine: The library is in the web/libraries/ckeditor-wordcount-plugin/ directory (as well as in the Vendor/w8tcha/ckeditor-wordcount-plugin/ directory where it isn't needed).

Maybe a composer require composer/installers is needed before to prevent composer from overwriting your modifications in composer.json file. But I am not sure if it is needed.

@guisharko:
Can you explain your solution from #12 more detailed. I think by creating your "wrapper" package the version is fixed and won't be updated automatically, right? And I didn't know which composer.json and where in that file your code should be placed.

M_Z’s picture

Maybe the best solution would be to add the ckeditor-wordcount-plugin library to https://www.drupal.org/project/ckeditor_libraries_group because under https://packagist.org/packages/drupal-ckeditor-libraries-group/ you can see the drupal-ckeditor-libraries-group/notification library that is correctly installed to the libraries directory by https://www.drupal.org/project/notification .

So why don't copy this working solution for this module's composer installation option?

jcnventura’s picture

Because this plugin is different. It is not packaged under the official CKEditor source like the others. It resides in its own repo.

RoSk0’s picture

Version: 8.x-1.1 » 8.x-1.x-dev
Component: Miscellaneous » Documentation
Category: Support request » Task
Status: Postponed » Needs work

Hello.

As correctly pointed out by @guisharko in #12 in order for Composer to install that library in the correct location w8tcha/CKEditor-WordCount-Plugin library should have type set to "drupal-library" because this is the directive (["type:drupal-library",) in the extra section that instructs installer-paths to install it at a specific path.

So, to "fix" this issue project page should be updated with the instructions for Composer based installations to include

{
            "type": "package",
            "package": {
                "name": "w8tcha/ckeditor-wordcount-plugin",
                "version": "1.17.8",
                "type": "drupal-library",
                "dist": {
                    "url": "https://github.com/w8tcha/CKEditor-WordCount-Plugin/releases/download/v1.17.8/CKEditor-WordCount-Plugin.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "~1.0"
                }
            }
        }

in the "repositories" section so it looks like :

"repositories": [
        {
            "type": "composer",
            "url": "https://packages.drupal.org/8"
        },
        {
            "type": "package",
            "package": {
                "name": "w8tcha/ckeditor-wordcount-plugin",
                "version": "1.17.8",
                "type": "drupal-library",
                "dist": {
                    "url": "https://github.com/w8tcha/CKEditor-WordCount-Plugin/releases/download/v1.17.8/CKEditor-WordCount-Plugin.zip",
                    "type": "zip"
                },
                "require": {
                    "composer/installers": "~1.0"
                }
            }
        }
    ]
RoSk0’s picture

Reading composer/installers docs again, especially https://github.com/composer/installers#custom-install-paths feels like it should be possible to install arbitrary package to a custom path by name, like suggested on the project page, but for some reason this doesn't work.

kevinquillen’s picture

Ran into this on D9 - trying what is listed on the description page does not work. #12 seems like the most sensible approach, because it will do that for anyone. I had to remove the module, add the package line, delete it from the vendor, and then require it again for it to download to the correct place. It helps to keep it generic that way, because it will download to the right place (the package is already tagged drupal-library per the composer addition) and not all users are using web as the webroot, some use docroot.

The reason it does not work, I believe, is because the package being requested (w8ctha plugin) is not tagged as a 'drupal-library' type at its source definition. Thats why it winds up in vendor, and not in libraries. This is why #12 works.

I think we should update that so its clear and consistent - the composer post install copy cmd is clever, but is likely too much to do just for this (also unsure if cp works on windows?).

kevinquillen’s picture

I updated the project page with the method from #12. I tried to be as thorough as possible. I just went through the process on a fresh install and it worked.

Can someone review?

kevinquillen’s picture

Status: Needs work » Needs review
kevinquillen’s picture

Just noticed its in the README too, and the linked GitHub thread indicates Composer is not going to change the way it does business in this regard.

I think we should get this resolved ASAP as its probably confusing new users.

jcnventura’s picture

I think here we need to follow webform's example and add a composer.libraries.json file to download the library. See https://www.drupal.org/docs/8/modules/webform/webform-frequently-asked-q...

Webbeh’s picture

Should wikimedia/composer-merge-plugin be used if it's been deprecated in core? #2912387: Stop using wikimedia/composer-merge-plugin

I suppose we could try a fork in https://www.drupal.org/project/ckeditor_libraries_group with the correct composer.json injection?

kevinquillen’s picture

Doesn't a composer.libraries.json just confuse the matter further? The end result is what adding the package to your composer.json is already.

jcnventura’s picture

@Webbeh, core had it's reasons for removing it. One of them was that it wasn't maintained. That used to be true. But since there was a new release 4 days ago, that point is no longer valid. I see many modules solving this problem using the composer.libraries.json solution, and I don't think we in the ckeditor_libraries_group can really solve this issue for all modules and all libraries. There's just too many of them, and this solution shifts the problem to module maintainers.

jcnventura’s picture

@kevinquillen, adding the composer.libraries.json is a possible solution to the problem. The other is adding the package repository as you've now documented in the module's page. Both solutions can exist side-by-side. Only that site builders that want to use composer.libraries.json will have it easier since they won't have to keep track of the library in their project's root composer.json.

jcnventura’s picture

Status: Needs review » Fixed
Related issues: +#3200823: Create a composer.libraries.json file

Marking this fixed, as the documentation on the module page now specifies fully how to add the library via a custom package repository to a site's root composer.json.

I've created a new issue to add the composer.libraries.json file that can be used as an alternative.

kevinquillen’s picture

The readme also needs updating

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.

NewZeal’s picture

I was not able to get this working by any of the methods outlined. Instead I am using this library: https://github.com/oomphinc/composer-installers-extender and ensured that my type name is prefixed with 'drupal-'. No need for any fancy packages in repositories or anything. Just ensure that the type name used in the custom module/library is the same as the one you want to save to your custom directory:

e.g in the module

{
  "name": "myproject/mymodule",
  "type": "drupal-myproject-custom-module",
  ...
}

And in the root composer.json:

          "web/modules/myproject/{$name}": [
                "type:drupal-myproject-custom-module"
           ],
jcnventura’s picture

@NewZeal, this thread is about installing the Javascript libraries required by this module, and not a custom module.

To install a custom module, you should not need to use "oomphinc/composer-installers-extender", but can instead use the "composer/installers" library, and give your module the standard "drupal-custom-module" type. See https://www.drupal.org/docs/develop/creating-modules/add-a-composerjson-... for more information.

NewZeal’s picture

My apologies. Actually, my intention is to install in a custom folder and not the standard "drupal-custom-module", for which the solution I provided seems essential.

jcnventura’s picture

It's a bit off-topic, but if you are OK with installing all your drupal-custom-module in the same directory, you should be fine with the base composer/installers package, and setting the directory in https://github.com/drupal/recommended-project/blob/10.1.x/composer.json#L54

Of course, if you want to install drupal-custom-module in web/modules/custom and some other custom module in web/modules/myproject, the yes, you need to define your own type for this drupal-myproject-custom-module cases. It does seem a bit too many levels of custom modules, but I'm pretty sure if you need that, that there are good reasons for it.

NewZeal’s picture

Yes, the reason for the custom folder is that the module has its own git repo that is made available as a package from gitlab, therefore it is not to be altered within the current repo. Meanwhile all modules under custom folder belong to the current repo and should be altered as required within the current repo.

Ludo.R’s picture

For me it worked like this:

Add this to composer.json

    "extra": {
        "merge-plugin": {
            "include": [
                "[web-root]/modules/contrib/ckwordcount/composer.libraries.json"
            ]
        }
    }

And then

composer require drupal/ckwordcount and not composer require drupal/ckwordcount w8tcha/ckeditor-wordcount-plugin.