swashata / wp-webpack-script

💥🔥📦👩‍💻 An easy to use, pre configured, hackable webpack setup & development server for WordPress themes and plugins.
https://wpack.io
MIT License
407 stars 58 forks source link

How are styles managed? #807

Closed simplenotezy closed 3 years ago

simplenotezy commented 4 years ago

I have completed the setup tutorials and set everything up. I see there is a lot of description for scripts etc, but not any information about the styles?

I'd like to use SCSS for my plugin.

Thanks in advance

simplenotezy commented 4 years ago

After playing a bit around with it, I realized this seems to work:

    {
        name: 'app',
        entry: {
            // In PHP: enqueue->enqueue( 'app', 'main', [] );
            butler: ['./src/app/butler.js', './src/app/test.scss'],
            // In PHP: enqueue->enqueue( 'app', 'mobile', [] );
            admin: ['./src/app/admin.js'],
        },
    }

Just weird that it isn't documented anywhere.

Next issue: how do I enqueue the stylesheet? I'm not sure if $this->instantButler->enqueue->enqueue( 'app', 'butler', [] ); is sufficient. Looking at the documentation: https://wpack.io/apis/php-api/#instance-api-enqueue it says Usage and parameters are same as getAssets. It returns the same list of assets as getAssets. does that mean that I have to use it the same way like below code?

$assets = $enqueue->getAssets( 'app', 'main', [
    'js' => true,
    'css' => true,
    'js_dep' => [],
    'css_dep' => [],
    'in_footer' => true,
    'media' => 'all',
] );

$jses = $assets['js'];
$csses = $assets['css'];

foreach ( $jses as $js ) {
    if ( $config['js'] ) {
        wp_enqueue_script( $js['handle'], $js['url'], [], '1.0.0', true );
    }
}

foreach ( $csses as $css ) {
    if ( $config['css'] ) {
        wp_enqueue_style( $css['handle'], $css['url'], $config['css_dep'], '1.0.0', 'all' );
    }
}
simplenotezy commented 4 years ago

I managed to do it like so:

$this->instantButler->getEnqueue()->enqueue( 'app', 'admin', ['js' => false, 'css' => true] );

Next question: what about images? How are these handled from /src/ to /dist/?

simplenotezy commented 4 years ago

OK. That seemed to work pretty easily. It works out of the box, expect for SVGs which was supported using: https://wpack.io/tutorials/using-various-svg-loader/#configure-1

Great!

The only thing is that I have noticed it only copies images that are used in the CSS, which is pretty cool, but also a disadvantage since we use some images referenced in the code and not in the CSS -- so how can I force it to be copied over to /dist/ folder, even though it is not referenced in scss?

swashata commented 4 years ago

Hi,

First of all, good to know you were able to figure this out. Now to clear your doubt a bit more (trust me, I have been there too)

I'd like to use SCSS for my plugin.

During setup, if you had selected sass, then you are good. Otherwise, put hasSass to true in project config and install node-sass with npm i -D node-sass.

how do I enqueue the stylesheet

First of all, in wepback like bundlers, sass or any style files aren't treated as separate entrypoint. Rather you import them from your main javascript entrypoint.

Say you have

    {
        name: 'app',
        entry: {
            // In PHP: enqueue->enqueue( 'app', 'main', [] );
            butler: ['./src/app/butler.js'],
            // In PHP: enqueue->enqueue( 'app', 'mobile', [] );
            admin: ['./src/app/admin.js'],
        },
    }

Then in butler.js you simply import the sass file needed.

butler.js

// this will do the trick
import './test.sass';
import somethingelse from 'something-else';
// ... etc

The tooling and PHP lib is smart enough to extract it to a separate .css file during build time and enqueue it automatically. No other action is necessary.

The only thing is that I have noticed it only copies images that are used in the CSS, which is pretty cool, but also a disadvantage since we use some images referenced in the code and not in the CSS -- so how can I force it to be copied over to /dist/ folder, even though it is not referenced in scss?

It has to be referenced somewhere, otherwise the tooling won't concern itself with. Do you see the fact that images are copied, but are given someother name? Like dist/app/assets/myFile-aaaaaa.jpg. This happens because webpack considers the image as a dependency of your sass file, which in turn is a dependency of your js file.

If you want to use any image from your javascript application, just do

butler.js

// this will do the trick
import './test.sass';
import imageURL from './files/myImage.jpg';

console.log(imageURL);
document.querySelector('img#myimage').setAttribute('src', imageURL);
// ... etc

In the above code, the tooling will take care of copying and giving you back image URL (absolute URL for any kind of server setup).

simplenotezy commented 4 years ago

Thanks @swashata for your indepth answer. In terms of images, how do I include it in a HTML file (not javascript)

swashata commented 4 years ago

Hello,

As I have mentioned before, this isn't possible with our bundler. You just have to do with old school PHP (get image link, print it in the page).