ゼロからreact+typescript足場を作ります.

29394 ワード

参考文献:私はこのようにTypecript+Reactプロジェクト環境を構築しました。
基本設定
webpack 4+に基づく構築
インストールwebpack:
npm install webpack@4 webpack-cli@3 -D
設定を保存するための新しいフォルダbuild.
mkdir build
次に、これらのファイルをbuildフォルダの下に新規作成します.
  • config.js環境変数
  • proxy.jsプロキシ構成
  • webpack.common.js汎用構成
  • webpack.dev.js開発環境構成
  • webpack.prod.js生産環境構成
  • $ cd build
    
    $ touch config.js proxy.js webpack.common.js webpack.dev.js webpack.prod.js
    次に二つの依存パッケージをインストールします.
  • webpack-mergeは、汎用構成webpack.com mmon.jsと開発環境devまたは生産環境prodの構成を統合することができる.
  • cross-envは、プラットフォームにまたがって環境変数を設定し、使用してもよい.macwindowの構成の異なる問題を解決する
  • .
    npm install webpack-merge cross-env -D
    変更package.jsonファイル:
    "scripts": {
        "start": "cross-env NODE_ENV=development webpack-dev-server --config ./build/webpack.dev.js",
        "build": "cross-env NODE_ENV=production webpack --config ./build/webpack.prod.js"
    }
    構築に必要な環境変数を準備し、config.jsを修正する.
    const SERVER_PORT = 9527
    const SERVER_HOST = '127.0.0.1'
    const PROJECT_NAME = "cli"
    const isDev = process.env.NODE_ENV !== 'production'
    
    module.exports = {
        isDev,
        PROJECT_NAME,
        SERVER_PORT,
        SERVER_HOST
    }
    次に、webpackプロファイルを準備します.
    // webpack.common.js
    const { resolve } = require('path')
    
    module.exports = {
      entry: resolve(__dirname,"../src/index.js"),
      output: {
        filename: 'js/bundle.[hash:8].js',
        path: resolve(__dirname, '../dist'),
      },
    }
    //webpack.dev.js
    const { merge } = require('webpack-merge')
    const common = require('./webpack.common.js')
    
    module.exports = merge(common, {
      mode: 'development',
    })
    //webpack.prod.js
    const { merge } = require('webpack-merge')
    const common = require('./webpack.common.js')
    
    module.exports = merge(common, {
      mode: 'production',
    })
    新規プロジェクト入口ファイル:
     src/
        - index.js
    プロジェクトを開始
    プロジェクトを起動するには、いくつかの設定依存パッケージが必要です.
  • html-webpack-pluginテンプレートファイルは、私たちが包装したリソースをhtmlに導入します.
  • webpack-dev-serverは、ローカルhttpサービスを開始し、熱更新、エージェントなどを構成することができる.
  • clean-webpack-pluginはフォルダを整理して、毎回包装した後に先に自動的に古いファイルを整理します.
  • copy-webpack-pluginは、リソースファイルをパッケージディレクトリにコピーする
  • .
    npm install html-webpack-plugin webpack-dev-server clean-webpack-plugin copy-webpack-plugin -D
    テンプレートの設定publicフォルダを新設して、中に私達のhtmlテンプレートファイルを入れます.
    mkdir public
    touch index.html
    //index.html
    
    
      
        
        
        
      
      
        <div id="root"/>
      
    </code></pre> 
     <p>   <code>htmlWebpackPlugin</code>            ,    <code>webpack.common.js</code>:</p> 
     <pre><code>const { resolve } = require('path')
    const config = require("./config")
    const CopyPlugin = require('copy-webpack-plugin')
    const HtmlWebpackPlugin = require('html-webpack-plugin')
    const { CleanWebpackPlugin } = require('clean-webpack-plugin')
    
    module.exports = {
      entry: "../src/index.tsx",
      output: {
        filename: 'js/bundle.[hash:8].js',
        path: resolve(__dirname, '../dist'),
        },
        plugins:[
            new HtmlWebpackPlugin({
                template: resolve(__dirname, '../public/index.html'),
                filename: 'index.html',
                title: config.PROJECT_NAME,
                cache: false,
            }),
            new CopyPlugin({
                patterns: [
                    { from: resolve(__dirname, "../public"), to: resolve(__dirname, "../dist") }
                ],
            }),
            new CleanWebpackPlugin()
        ]
    }</code></pre> 
     <h3>devServer   </h3> 
     <h4>  </h4> 
     <p>  <code>proxy.js</code>,    :</p> 
     <pre><code>const proxySetting = {
        '/api/': {
            target: 'http://localhost:3001',
            changeOrigin: true,
        },
        //    2
        '/api-2/': {
            target: 'http://localhost:3002',
            changeOrigin: true,
            pathRewrite: {
                '^/api-2': '',
            },
        },
    }
    
    module.exports = proxySetting</code></pre> 
     <h3>devServer</h3> 
     <p>   <code>webpack.dev.js</code>:</p> 
     <pre><code>const { merge } = require('webpack-merge');
    const webpack = require('webpack');
    const {resolve} = require("path");
    const common = require('./webpack.common.js');
    const proxySetting = require('./proxy');
    const config = require('./config');
    
    module.exports = merge(common, {
        mode: 'development',
        devServer: {
            host: config.SERVER_HOST,
            port: config.SERVER_PORT,
            stats: 'errors-only',
            clientLogLevel: 'silent',
            compress: true,
            open: false,
            hot: true, //    
            proxy: { ...proxySetting }, //     
            contentBase: resolve(__dirname, '../public')
        },
        plugins: [new webpack.HotModuleReplacementPlugin()],
    });
    </code></pre> 
     <h3>devtool</h3> 
     <p><code>devtool</code>                 ,          ,    <code>eval-source-map</code>          ,         ,      :</p> 
     <pre><code>//webpack.dev.js
    module.exports = merge(common, {
      mode: 'development',
    + devtool: 'eval-source-map',
    })</code></pre> 
     <pre><code>//webpack.prod.js
    module.exports = merge(common, {
      mode: 'production',
    + devtool: 'none',
    })</code></pre> 
     <h2>    </h2> 
     <p><code>style-loader</code> <code>css-loader</code>     ,        <code>less</code>  ,    <code>less</code> <code>less-loader</code>。  <code>sass</code>    <code>node-sass</code> <code>sass-loader</code>,      <code>less</code>,    :</p> 
     <pre><code>npm install css-loader style-loader less less-loader -D</code></pre> 
     <p>           <code>rule</code>,  <code>css</code>   <code>less</code>     :</p> 
     <pre><code>// webpack.common.js
    module.exports = {
      // other...
      module: {
        rules: [
          {test: /\.css$/,use: ['style-loader','css-loader']},
          {test: /\.less$/,use: [
            'style-loader',
            {
                loader:'css-loader',
                options:{importLoaders:1}
            },
            'less-loader'
            ]
        },
        ]
      },
    }</code></pre> 
     <p>                       <em>sourceMap</em></p> 
     <h3>postcss     </h3> 
     <p><code>postcss</code>  <em>babel</em>  ,        <em>preset</em>    :</p> 
     <ul> 
      <li><a href="https://github.com/luisrudge/postcss-flexbugs-fixes" rel="nofollow noreferrer">postcss-flexbugs-fixes</a>:        flex       bug。</li> 
      <li><a href="https://github.com/csstools/postcss-preset-env" rel="nofollow noreferrer">postcss-preset-env</a>:     CSS                    CSS   ,                  。     autoprefixer          。</li> 
      <li><a href="https://github.com/csstools/postcss-normalize" rel="nofollow noreferrer">postcss-normalize</a>:  browserslist           normalize.css   。</li> 
     </ul> 
     <pre><code>npm install postcss-loader postcss-flexbugs-fixes postcss-preset-env autoprefixer postcss-normalize -D</code></pre> 
     <p><code>postcss</code>      :</p> 
     <pre><code>{
        loader: 'postcss-loader',
        options: {
            sourceMap: config.isDev, //      sourceMap
            postcssOptions: {
                plugins: [
                    //       flex       bug
                    require('postcss-flexbugs-fixes'),
                    require('postcss-preset-env')({
                        autoprefixer: {grid: true,flexbox: 'no-2009'},
                        stage: 3,
                    }),
                    require('postcss-normalize')]}
            }
    }</code></pre> 
     <p>      <code>css</code> <code>less</code>        ,                ,<br/><em>build</em>      <code>utils.js</code>  ,           :</p> 
     <pre><code>//utils.js
    const {isDev} = require('./config')
    
    exports.getCssLoaders = (importLoaders) => [
        'style-loader',
        {
            loader: 'css-loader',
            options: {
                modules: false,
                sourceMap: isDev,
                importLoaders,
            },
        },
        {
            loader: 'postcss-loader',
            options: {
                sourceMap: isDev,
                postcssOptions: {
                    plugins: [
                        //       flex       bug
                        require('postcss-flexbugs-fixes'),
                        require('postcss-preset-env')({
                            autoprefixer: {
                                grid: true,
                                flexbox: 'no-2009',
                            },
                            stage: 3,
                        }),
                        require('postcss-normalize'),
                    ],
                },
            },
        },
    ]</code></pre> 
     <p>    <code>webpack.common.js</code>  :</p> 
     <pre><code>const {getCssLoaders} = require("./utils");
    
    ...
        module:{
            rules:[
                { test: /.(css)$/, use: getCssLoaders(1) },
                {
                    test: /\.less$/,
                    use: [
                        ...getCssLoaders(2),
                        {
                            loader: 'less-loader',
                            options: {sourceMap: config.isDev},
                        }
                    ]
                }
            ]
        }
    ...</code></pre> 
     <p>  ,     <code>package.json</code>     <code>browserslist</code>:</p> 
     <pre><code>{
      "browserslist": [
        ">0.2%",
        "not dead",
        "ie >= 9",
        "not op_mini all"
      ],
    }</code></pre> 
     <h3>         </h3> 
     <p>               ,      <code>url-loader</code>  ,             base64,        ,  <code>file-loader</code>        ,      :</p> 
     <pre><code>npm install file-loader url-loader -D</code></pre> 
     <pre><code>// webpack.common.js
    
    module.exports = {
      // other...
      module: {
        rules: [
          // other...
          {
            test: [/\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/],
            use: [
              {
                loader: 'url-loader',
                options: {
                  limit: 10 * 1024,
                  name: '[name].[contenthash:8].[ext]',
                  outputPath: 'assets/images',
                },
              },
            ],
          },
          {
            test: /\.(ttf|woff|woff2|eot|otf|svg)$/,
            use: [
              {
                loader: 'file-loader',
                options: {
                  name: '[name].[contenthash:8].[ext]',
                  outputPath: 'assets/fonts',
                },
              },
            ],
          },
        ]
      },
      plugins: [//...],
    }</code></pre> 
     <p><code>typescript</code>          ,   <code>src/typings</code>   <code>file.d.ts</code>  ,      :</p> 
     <pre><code>declare module '*.svg' {
      const path: string
      export default path
    }
    
    declare module '*.bmp' {
      const path: string
      export default path
    }
    
    declare module '*.gif' {
      const path: string
      export default path
    }
    
    declare module '*.jpg' {
      const path: string
      export default path
    }
    
    declare module '*.jpeg' {
      const path: string
      export default path
    }
    
    declare module '*.png' {
      const path: string
      export default path
    }</code></pre> 
     <h3>react   typescript</h3> 
     <p>   <code>react</code>:</p> 
     <pre><code>npm install react react-dom -S</code></pre> 
     <p>  <code>babel</code>    :</p> 
     <pre><code>npm install babel-loader @babel/core @babel/preset-env @babel/plugin-transform-runtime @babel/preset-react -D</code></pre> 
     <pre><code>npm install @babel/runtime-corejs3 -S</code></pre> 
     <blockquote>
         : @babel/runtime-corejs3         。 
     </blockquote> 
     <ul> 
      <li><strong>babel-loader</strong>   <code>babel</code>    </li> 
      <li><strong>@babel/core</strong> <code>babel</code>    </li> 
      <li><strong>@babel/preset-env</strong>        javascript   </li> 
      <li><strong>@babel/preset-react</strong>    jsx   </li> 
      <li><strong>@babel/plugin-transform-runtime</strong>    /  、        (helper function)</li> 
      <li><strong>@babel/runtime-corejs3</strong>     </li> 
     </ul> 
     <p>  <code>.babelrc</code>,      :</p> 
     <pre><code>{
      "presets": [
        [
          "@babel/preset-env",
          {
            //   babel           CommonJS  ,  tree-shaking    
            "modules": false
          }
        ],
        "@babel/preset-react"
      ],
      "plugins": [
        [
          "@babel/plugin-transform-runtime",
          {
            "corejs": {
              "version": 3,
              "proposals": true
            },
            "useESModules": true
          }
        ]
      ]
    }</code></pre> 
     <p>   <code>webpack.common.js</code>   ,      :</p> 
     <pre><code>module.exports = {
        // other...
      module: {
        rules: [
          {
            test: /\.(tsx?|js)$/,
            loader: 'babel-loader',
            options: { cacheDirectory: true },
            exclude: /node_modules/,
          },
          // other...
        ]
      },
      plugins: [ //... ],
    }</code></pre> 
     <blockquote>
       babel-loader       ,                  ,         ,          ,       cacheDirectory            ,          。 
     </blockquote> 
     <h4>resolve.extensions   resolve.alias</h4> 
     <ul> 
      <li><code>extensions</code>      </li> 
      <li><code>alias</code>   </li> 
     </ul> 
     <p>  <code>webpack.common.js</code>    <code>resolve</code>:</p> 
     <pre><code>resolve: {
        alias:{"@":resolve(__dirname, '../src')},
        extensions: ['.tsx', '.ts', '.js', '.json'],
    },</code></pre> 
     <h4>   typescript</h4> 
     <p>  <code>src/index.js</code>   <code>src/index.tsx</code>:</p> 
     <pre><code>entry: {
        app: resolve(__dirname, '../src/index.tsx'),
    },</code></pre> 
     <p>   Typescript       <code>tsconfig.json</code>   ,         :</p> 
     <ul> 
      <li>       </li> 
      <li>       </li> 
     </ul> 
     <p>              <code>tsconfig.json</code>  :</p> 
     <pre><code>npx tsc --init</code></pre> 
     <p>   <code>tsconfig.json</code>          ,    <a href="https://jkchao.github.io/typescript-book-chinese/project/compilationContext.html#tsconfig-json" rel="nofollow noreferrer">     TypeScript-tsconfig-json</a>    ,  <code>tsconfig.json</code>,      :</p> 
     <pre><code>{
      "compilerOptions": {
        //     
        "target": "ES5",                          //          es
        "module": "ESNext",                       //             
        "lib": ["dom", "dom.iterable", "esnext"], //                 
        "allowJs": true,                          //      js   
        "jsx": "react",                           //   .tsx       JSX
        "isolatedModules": true,
        "strict": true,                           //             
            "noImplicitAny": false, //   any  
    
        //       
        "moduleResolution": "node",               //         
        "esModuleInterop": true,                  //    CommonJS   ES          
        "resolveJsonModule": true,                //      json   
        "baseUrl": "./",                          //    
        "paths": {                                //     ,  baseUrl   
          "@/*": ["src/*"],
        },
    
        //      
        "experimentalDecorators": true,           //       ES   
        "emitDecoratorMetadata": true,            //                    
    
        //     
        "forceConsistentCasingInFileNames": true, //                
        "skipLibCheck": true,                     //          ( *.d.ts)     
        "allowSyntheticDefaultImports": true,     //                    
        "noEmit": true                                                      //     tsc          (     (  Babel    ) )   
      },
      "exclude": ["node_modules"]
    }</code></pre> 
     <p>  <code>eslint</code>   ,     <code>baseUrl</code> <code>paths</code>       ,              :</p> 
     <pre><code>npm install eslint-import-resolver-typescript -D</code></pre> 
     <p>   eslintrc.js     setting   :</p> 
     <pre><code>settings: {
      'import/resolver': {
        node: {
          extensions: ['.tsx', '.ts', '.js', '.json'],
        },
        typescript: {},
      },
    },</code></pre> 
     <p>    <code>typescript</code>    <code>@babel/preset-typescript</code> <code>fork-ts-checker-webpack-plugin</code></p> 
     <ul> 
      <li><code>@babel/preset-typescript </code>   ts      ,     ts      ,     babel       </li> 
      <li><code>fork-ts-checker-webpack-plugin</code>     <code>preset-typescript</code>          ,                           </li> 
     </ul> 
     <p>    :</p> 
     <pre><code>npm install @babel/preset-typescript fork-ts-checker-webpack-plugin -D</code></pre> 
     <p> <code>webpack.common.js</code>      :</p> 
     <pre><code>const ForkTsCheckerWebpackPlugin = require('fork-ts-checker-webpack-plugin')
    
    module.exports = {
        plugins: [
        //    plugin...
        new ForkTsCheckerWebpackPlugin({
          typescript: {
            configFile: resolve(__dirname, '../tsconfig.json'),
          },
        }),
      ]
    }</code></pre> 
     <p> <code>.babelrc</code>    <code>preset-typescript</code> :</p> 
     <pre><code>"presets": [
        [
        //...
        "@babel/preset-typescript"
      ]</code></pre> 
     <p>    <code>React</code>      :</p> 
     <pre><code>npm install @types/react @types/react-dom -D</code></pre> 
     <h4>  </h4> 
     <p><code>src</code>      <code>index.tsx</code> <code>App.tsx</code>  ,        :</p> 
     <ul> 
      <li>index.tsx</li> 
     </ul> 
     <pre><code>import React from "react";
    import ReactDOM from "react-dom";
    import App from "./App";
    
    ReactDOM.render(<app age="{12}" name="test"/>, document.querySelector("#root"));</code></pre> 
     <ul> 
      <li>App.tsx</li> 
     </ul> 
     <pre><code>import React from "react";
    
    interface IProps {
        name: string;
        age: number;
    }
    
    function App(props: IProps) {
        const { name, age } = props;
        return (
            <div classname="app">
                <span>{`Hello! I'm ${name}, ${age} years old.`}</span>
            </div>
        );
    }
    
    export default App;</code></pre> 
     <h2>  </h2> 
     <h3>      </h3> 
     <blockquote> 
      <code>webpackbar</code>                   
     </blockquote> 
     <pre><code>npm install webpackbar -D</code></pre> 
     <p>  webpack.common.js       :</p> 
     <pre><code>const WebpackBar = require("webpackbar");
    
    class Reporter {
        done(context) {
            if (config.isDev) {
                console.clear();
                console.log(`    :${config.SERVER_HOST}:${config.SERVER_PORT}`);
            }
        }
    }
    
    module.exports = {
        plugins: [
        //    plugin...
        new WebpackBar({
                name: config.isDev ? "    " : "    ",
                color: "#fa8c16",
                reporter: new Reporter()
            })
      ]
    }</code></pre> 
     <h3>        </h3> 
     <blockquote> 
      <code>hard-source-webpack-plugin</code>        (  lodash)         ,      node_modules/.cache/hard-source   ,                   ,            ,                   
     </blockquote> 
     <pre><code>npm install hard-source-webpack-plugin -D</code></pre> 
     <p>  <code>webpack.common.js</code>        :</p> 
     <pre><code>const HardSourceWebpackPlugin = require('hard-source-webpack-plugin')
    
    module.exports = {
        plugins: [
        //    plugin...
        new HardSourceWebpackPlugin(),
      ]
    }</code></pre> 
     <h3>external       </h3> 
     <blockquote>
                
      <code>react</code>、 
      <code>react-dom</code>           ,                  CDN      
     </blockquote> 
     <p>   webpack.common.js ,      :</p> 
     <pre><code>module.exports = {
      externals: {
        react: 'React',
        'react-dom': 'ReactDOM',
      },
    }</code></pre> 
     <p>          </p> 
     <ul> 
      <li>CDN     :</li> 
     </ul> 
     <pre><code>
    
      
        <div id="root"/>
    +   <script crossorigin="" src="https://unpkg.com/react@16.13.1/umd/react.production.min.js"/>
    +   <script crossorigin="" src="https://unpkg.com/react-dom@16.13.1/umd/react-dom.production.min.js"/>
      
    </code></pre> 
     <ul> 
      <li>    :</li> 
     </ul> 
     <p> <code>public</code>      <code>lib</code>   ,         :</p> 
     <pre><code>public/
        index.html
        lib/
            react.production.min.js
            react-dom.production.min.js</code></pre> 
     <h3>DllPlugin</h3> 
     <p>       dll                       ,       ,       <a href="https://github.com/asfktz/autodll-webpack-plugin" rel="nofollow noreferrer">autodll-webpack-plugin</a>;</p> 
     <h3>splitChunks</h3> 
     <p>React        <code>React.lazy</code>   <code>React.Suspense</code>      ,          :</p> 
     <pre><code>import React, { Suspense, useState } from 'react'
    
    const ComputedOne = React.lazy(() => import('Components/ComputedOne'))
    const ComputedTwo = React.lazy(() => import('Components/ComputedTwo'))
    
    function App() {
     const [showTwo, setShowTwo] = useState<boolean>(false)
    
     return (
       <div classname="app">
         <suspense fallback="{<div">Loading...</suspense></div>}>
           <computedone a="{1}" b="{2}"/>
           {showTwo && <computedtwo a="{3}" b="{4}"/>}
           <button type="button" onclick="{()"> setShowTwo(true)}>
               Two
           </button>
         
       </boolean></code></pre></article></div>
     )
    }
    
    export default App
     
     <p>                  <code>chunk</code>   ,               chunk,    webpack.common.js        :</p> 
     <pre><code>module.exports = {
        // other...
      externals: {//...},
      optimization: {
        splitChunks: {
          chunks: 'all',
          name: true,
        },
      },
    }</code></pre> 
     <h3>   </h3> 
     <p>   <strong>devServer</strong>             ,     js                ,         <code>index.jsx</code>    :</p> 
     <pre><code>if (module && module.hot) {
      module.hot.accept()
    }</code></pre> 
     <p>   ts    ,           ,      <code>@types/webpack-env</code>:</p> 
     <pre><code>npm install @types/webpack-env -D</code></pre> 
     <h2>      </h2> 
     <h3>    </h3> 
     <h4>    </h4> 
     <p>  <code>mini-css-extract-plugin</code>:</p> 
     <pre><code>npm install mini-css-extract-plugin -D</code></pre> 
     <p><code>build/utils.js</code>      :</p> 
     <pre><code>const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    const getCssLoaders = (importLoaders) => [
      isDev ? 'style-loader' : MiniCssExtractPlugin.loader,
      // ....
    ]</code></pre> 
     <p><code>webpack.prop.js</code>      :</p> 
     <pre><code>const MiniCssExtractPlugin = require('mini-css-extract-plugin')
    
    module.exports = {
        plugins: [
        //    plugin...
        new MiniCssExtractPlugin({
          filename: 'css/[name].[contenthash:8].css',
          chunkFilename: 'css/[name].[contenthash:8].css',
          ignoreOrder: false,
        }),
      ]
    }</code></pre> 
     <h4>      </h4> 
     <pre><code>npm install purgecss-webpack-plugin glob -D</code></pre> 
     <p><code>webpack.prop.js</code>      :</p> 
     <pre><code>const glob = require("glob");
    const PurgeCSSPlugin = require('purgecss-webpack-plugin')
    const { resolve } = require("path");
    
    module.exports = merge(common, {
      plugins: [
        // ...
        new PurgeCSSPlugin({
                paths: glob.sync(`${resolve(__dirname, "../src")}/**/*.{tsx,scss,less,css}`, {
                    nodir: true
                }),
                whitelist: ["html", "body"]
            })
      ],
    })</code></pre> 
     <h3>    </h3> 
     <pre><code>npm install optimize-css-assets-webpack-plugin terser-webpack-plugin@4 -D</code></pre> 
     <p><code>webpack.prop.js</code>      :</p> 
     <pre><code>const TerserPlugin = require("terser-webpack-plugin");
    const OptimizeCssAssetsPlugin = require('optimize-css-assets-webpack-plugin')
    
    module.exports = merge(common, {
        //...
      optimization: {
            minimize: true,
            minimizer: [
                new TerserPlugin({
                    extractComments: false,
                    terserOptions: {
                        compress: { pure_funcs: ["console.log"] }
                    }
                }),
                new OptimizeCssAssetsPlugin()
            ]
        },
        plugins:[...]
    })</code></pre> 
     <h3>     </h3> 
     <p><code>webpack.prop.js</code>      :</p> 
     <pre><code>const webpack = require('webpack')
    
    module.exports = merge(common, {
      plugins: [
        // ...
        new webpack.BannerPlugin({
          raw: true,
          banner: '/** @preserve Powered by chenwl */',
        }),
      ]
    })</code></pre> 
     <h3>    </h3> 
     <pre><code>npm install webpack-bundle-analyzer -D</code></pre> 
     <p><code>webpack.prop.js</code>      :</p> 
     <pre><code>const { BundleAnalyzerPlugin } = require('webpack-bundle-analyzer')
    
    module.exports = merge(common, {
      plugins: [
        // ...
        new BundleAnalyzerPlugin({
          analyzerMode: 'server',                   //            
          analyzerHost: '127.0.0.1',            // host   
          analyzerPort: 8081,                           //      
        }),
      ],
    })</code></pre> 
    
                                </div>