JoviDeCroock / webpack-module-nomodule-plugin

Easily implement a module nomodule index.html
82 stars 6 forks source link

How to build two bundles for module and nomodule? #13

Closed 00King00 closed 4 years ago

00King00 commented 4 years ago

my folders structure: ... public resources ... webpack.config.js webpack-prod.config.js

code inside webpack.config.js:

const path = require("path");
const ROOT = path.resolve(__dirname, "resources");
const templateCache = require("./templateCache");
const MiniCssExtractPlugin = require("mini-css-extract-plugin");
const VueLoaderPlugin = require('vue-loader/lib/plugin');
const DESTINATION = path.resolve( __dirname, 'public/build' );//*

module.exports = {
  mode: "development",
  context: ROOT,
  resolve: {
    extensions: [".js"],
    alias: {
      "@": path.resolve(__dirname, "viewneo-components/components"),
      "~": path.resolve(__dirname, "viewneo-components"),
    }
  },
  module: {
    rules: [
      {
        test: /\.m?js$/,
        exclude: /(node_modules)/,
        use: {
          loader: "babel-loader",
          options: {
            presets: ["@babel/preset-env"]
          }
        }
      },
      {
        test: /\.vue$/,
        use: 'vue-loader'
      },
      {
        test: /\.(css|sass|scss)$/,
        use: [
          MiniCssExtractPlugin.loader,
          "css-loader",
          "postcss-loader",
          { loader: "resolve-url-loader", options: { 
            // engine: "rework",
            // root: '',
            } 
          },
          { loader: "sass-loader", options: { prependData: '@import "~/assets/scss/style.scss";' } }
        ]
      },
      {
        test: /\.(jpg|png|gif|svg)$/,
        use: [
          {
            loader: "file-loader",
            options: {
              esModule: false,
              name: '../[contenthash].[ext]',
            }
          }
        ]
      },
      {
        test: /\.(woff|woff2|eot|ttf)$/,
        use: "file-loader?outputPath=fonts/"
      }
    ]
  },

  plugins: [
    new MiniCssExtractPlugin({
      filename: "css/app.css"
    }),
    new VueLoaderPlugin(),
    require('autoprefixer')
  ],

  entry: ["./assets/sass/app.scss", "./assets/js/app.js"],
  output: {
      path: DESTINATION,
      filename: 'js/app.js'
  },
};

================================================================

code inside webpack-prod.config.js:

const path = require('path');
const webpackMerge = require('webpack-merge');
const WebpackModuleNomodulePlugin = require('webpack-module-nomodule-plugin');
const commonConfig = require('./webpack.config.js');
const TerserPlugin = require('terser-webpack-plugin');
const DESTINATION = path.resolve( __dirname, 'public/build' ); 

module.exports = webpackMerge(commonConfig, {
    mode: 'production',
    optimization:{
        minimize: true,
        minimizer: [
          new TerserPlugin({ // TODO optimize bundle size
            extractComments: 'all',
            terserOptions: {
              ecma: undefined,
              warnings: false,
              parse: {},
              compress: {},
              mangle: false,
              module: false,
              output: null,
              toplevel: false,
              nameCache: false,
              ie8: false,
              keep_classnames: false,
              keep_fnames: false,
              safari10: false,
            },
          }),
        ],
    },
    plugins: [
      new WebpackModuleNomodulePlugin('legacy'),
    ]

});
JoviDeCroock commented 4 years ago

I'm having a lot of issues reading your issue but here's an example of me using it example found at the bottom of the readme.

00King00 commented 4 years ago

I'm having a lot of issues reading your issue but here's an example of me using it example found at the bottom of the readme. Thanks for your replay! I read it and did copy, made a build and this is work. But for me is not clear if I need to make configuration with 'bable-loader' and 'output' inside webpack.config.js when I use WebpackModuleNomodulePlugin in my own config?

JoviDeCroock commented 4 years ago

Could you try to define your issue, providing code with backticks makes it readable on the markdown format. You could also try and upload your repo, essentially GH issues aren’t meant for this. I’d gladly help but it’s hard in an unformatted document.

Essentially you need two babel configs one for modern and one for legacy because this actually makes the difference in outputted code. In modern you’ll target modern browsers in legacy you won’t.

I tried reading your config and you’re supplying the plugin twice rather than starting two compilations as shown in my example.

00King00 commented 4 years ago

JoviDeCroock I'm so sorry my fault just formatted code and invoke only one WebpackModuleNomodulePlugin.

JoviDeCroock commented 4 years ago

No need for apologizing, if you encounter a bug,... feel free to hit me up. Good luck!

00King00 commented 4 years ago

Thank you! But why if I invoke new WebpackModuleNomodulePlugin('legacy'), or WebpackModuleNomodulePlugin('modern') I get the same bundle size. Maybe I need to remove babel-loader in my config? My config is correct? I will be grateful for your help.

JoviDeCroock commented 4 years ago

Your bundle size will only be different in these conditions:

It's important to note that noone is transpiling node_modules at the moment since these are published as ES5 and can't be upgraded to ES6, this means that the impact of this optimization is only noticeable in your own written code.

In my example we support modules that support script type="module" and the legacy is meant for to support old browsers so we have to tailor our transpilation to be down to those browsers.

Extra optimizations might include selectively polyfilling features like fetch and tailoring terser for modern code

In your example you are always transpiling down to a low level rather than differentiating.