Kocal / vue-web-extension

🛠️ A Vue CLI 3+ preset (previously a Vue CLI 2 boilerplate) for quickly starting a web extension with Vue, Babel, ESLint and more!
https://vue-web-extension.netlify.app/
MIT License
1.58k stars 167 forks source link

Adding TailwindCSS #576

Closed spekulatius closed 4 years ago

spekulatius commented 4 years ago

Hey @Kocal,

thank you for building this amazing boilerplate. It saves me a lot of work! However, I'm stuck in adding TailwindCSS atm. I've attempted to follow the NPM installation steps here: https://tailwindcss.com/docs/installation/#1-install-tailwind-via-npm but can't get it working - the Tailwind components aren't added to the CSS at the end. Not sure what I'm missing. Is there an example somewhere on to how do add a PostCSS process to the boilerplate?

Cheers, Peter

Kocal commented 4 years ago

Hi, and thank you! :)

When you say Tailwind components, are you speaking about @tailwind components? Because, if I am not wrong, it will import this small file, a single responsive .container class. Do you use it this class? If no, maybe it's purged by PurgeCSS?

Do @tailwind base and @tailwind utilities are working for you?

Unfornatelly, I've used Tailwind but only with Webpack Encore, not with raw Webpack config.

I can't test it locally, but the following steps should work:

  1. Install dependencies postcss-loader @fullhuman/postcss-purgecss
  2. Update your webpack.config.js to use postcss-loader:
      {
        test: /\.css$/,
    +        use: [MiniCssExtractPlugin.loader, 'css-loader'],
    -        use: [MiniCssExtractPlugin.loader, 'css-loader', 'postcss-loader'],
      },
  3. Create a postcss.config.js:
    
    /* eslint-disable import/no-extraneous-dependencies */

const tailwindcss = require('tailwindcss');

const purgecss = require('@fullhuman/postcss-purgecss')({ // Specify the paths to all of the template files in your project content: ['./src/*/.vue'],

// Include any special characters you're using in this regular expression defaultExtractor: (content) => content.match(/[\w-/:]+(?<!:)/g) || [],

extractors: [ // https://purgecss.com/guides/vue.html { extensions: ['vue'], extractor(content) { const contentWithoutStyleBlocks = content.replace(/<style[^]+?<\/style>/gi, ''); return contentWithoutStyleBlocks.match(/[A-Za-z0-9-/:]*[A-Za-z0-9-/]+/g) || []; }, }, ],

whitelist: [], whitelistPatterns: [ /-(leave|enter|appear)(|-(to|from|active))$/, // transitions /data-v-.*/, // scoped css ], });

module.exports = { plugins: [tailwindcss(), ...(process.env.NODE_ENV === 'production' ? [purgecss] : [])], };



Tell me if it resolved your issue, also feel free to make a reproduction repository if you need more help!
spekulatius commented 4 years ago

Hello @Kocal,

thanks for your detailed reply! It helped me getting it working! The output is containing the full, non-minimized Tailwind now. The @tailwind directives are resolved now :)

Would you happen to know how I can purge the unneeded CSS classes too?

Peter

Kocal commented 4 years ago

Nice!

If you take a look to the postcss.config.js, you can see that PurgeCSS plugin is enabled only for production (process.env.NODE_ENV === 'production').

If you want to purge un-needed CSS, you should run yarn run build (which should normally run cross-env NODE_ENV=production webpack --hide-modules)

spekulatius commented 4 years ago

Ah, yes! I should have checked the build configuration more - you are right @Kocal. It's in there and works. I've run yarn build and it reduced the CSS to 13k :) Thank you so much for your help!

quanengineering commented 4 years ago

Thanks, @Kocal. It purged like a charm, but I still have some questions.

Thanks in advance.

Kocal commented 4 years ago

Hi @quannetwork,

Is that because you use Tailwind's native PurgeCSS integration? It seems that is enabled automatically when NODE_ENV is equal to production, you can configure purge: false in Tailwind config file and it should works.

To minify your CSS, you can use the OptimizeCssAssetsPlugin webpack plugin, in your weback.config.js at this line:

if (config.mode === 'production') {
  config.plugins = (config.plugins || []).concat([
    // ...
    new OptimizeCssAssetsPlugin(),
  ]);
}

You popup.js is 90Kb even with vendor chunks splitting? What do you import in your popop?

quanengineering commented 4 years ago

Thanks, @Kocal, I did it. After minified, it's only 3.8Kb, so small <3. I also add this option to remove comments.

    new OptimizeCssAssetsPlugin({
      cssProcessorPluginOptions: {
        preset: ['default', { discardComments: { removeAll: true } }],
      },
    }),
Kocal commented 4 years ago

Nice!

quanengineering commented 4 years ago

About the popup.js, here's what I imported:

import Vue from 'vue';
import App from './App';
import store from '../store';
global.browser = require('webextension-polyfill');
import axios from 'axios';
import Vuex from 'vuex';

That's all the 3rd library I used. The global.browser = require('webextension-polyfill'); imported several times I different files, I think it's not the problem.

fergalmoran commented 4 years ago

Guys, would anyone have a project they could share with me on this one? I've tried everything here but still not getting anywhere... Do I need to change the build scripts in package.json ?

spekulatius commented 4 years ago

Guys, would anyone have a project they could share with me on this one? I've tried everything here but still not getting anywhere... Do I need to change the build scripts in package.json ?

You struggle to Tailwind up and running?

fergalmoran commented 4 years ago

Guys, would anyone have a project they could share with me on this one? I've tried everything here but still not getting anywhere... Do I need to change the build scripts in package.json ?

You struggle to Tailwind up and running?

Yes, I've done everything detailed in your first reply but no tailwind css classes work?

spekulatius commented 4 years ago

The steps helped me. Can you share your package.json and webpack.config.js?

vagnersabadi commented 4 years ago

Does anyone have an example project? can't add so far.

spekulatius commented 4 years ago

Hello @vagnersabadi

can you check if this works for you: https://vue-web-extension.netlify.app/development/TailwindCSS.html

Cheers, Peter

vagnersabadi commented 4 years ago

Hello @vagnersabadi

can you check if this works for you: https://vue-web-extension.netlify.app/development/TailwindCSS.html

Cheers, Peter

I tried to follow the documentation but without success. Error is occurring when generating the build with npm run build and displays the following error message:

ERROR in ./options/App.vue
Module not found: Error: Can't resolve 'postcss-loader' in '/Users/mac-dev/Projetos/_vue/my-extension/src'
 @ ./options/App.vue 4:0-87
 @ ./options/options.js

ERROR in ./popup/App.vue
Module not found: Error: Can't resolve 'postcss-loader' in '/Users/mac-dev/Projetos/_vue/my-extension/src'
 @ ./popup/App.vue 4:0-63
 @ ./popup/popup.js

I created a project to show https://github.com/vagnersabadi/my-extension

spekulatius commented 4 years ago

Hello @vagnersabadi

the error message indicates that the library isn't installed, but your package.json has it listed. Can you tried to delete the node_modules folder and re-install it (npm install or yarn)?

Peter

fredrivett commented 3 years ago

The tweaks @Kocal mentioned here provided the basis, but for my specific use case I needed to make these changes:

      {
        test: /\.css$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
+         "postcss-loader"
        ],
      },
      {
        test: /\.scss$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
+         "postcss-loader",
          "sass-loader",
        ],
      },
      {
        test: /\.sass$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
+         "postcss-loader",
          "sass-loader?indentedSyntax",
        ],
      },

note: I'm not entirely sure why, but it's important that the postcss-loader comes after the css-loader and before the sass-loader, it didn't work for me adding it after the sass-loader.

awardx commented 3 years ago

New Tailwind JIT feature

Finally got it working on v1 boilerplate (I'm still using that with my old project). Anyways... Here's what I've done:

// postcss.config.js

module.exports = {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
// tailwind.config.js

module.exports = {
    mode: 'jit',
    purge: {
        // Specify the paths to all of the template files in your project
        content: ['src/**/*.vue'],

        // Whitelist selectors by using regular expression
        whitelistPatterns: [
            /-(leave|enter|appear)(|-(to|from|active))$/, // transitions
            /data-v-.*/, // scoped css
        ],
    },
    // ...
}

npm install postcss postcss-cli BTW I'm running postcss v7.0.36 along with npm:@tailwindcss/postcss7-compat@^2.2.7

npx tailwindcss-cli@latest build -i ./src/assets/css/tailwind.css -o ./src/assets/css/buildtw.css --watch

Then in your entry .js file such as content-script.js so you can use Tailwind within all your child components

import Vue from 'vue';
import 'path_to_your/buildtw.css'
// ...

Finally, npm run watch:dev in a separate terminal to watch for changes in your components. Now you can compile "thin" .css with new Tailwind JIT functionality to be able to do things like text-[#7724ab]. Every time you update your component class, Tailwind will re-compile a new buildtw.css file in 100s of a second and WER will reload the page with a new css class enabled.

Cheers