웹팩 개발 온 가족 통

웹팩 개발 온 가족 통

  • 개발 환경 구성
  • webpack-dev-server
  • devServer 설정 정적 자원 서버 경로 지정
  • 프록시 서비스 구성, 개발 환경 인터페이스 크로스 도메인 문제 해결
  • Source Map 구성
  • HMR — Hot Module Replacement
  • 사용법
  • HMR 고려사항

  • 다중 환경 구성
  • 환경에 따라 다양한 구성 내보내기
  • 하나의 환경에 대한 구성 파일
  • DefinePlugin
  • 예제
  • 웹팩 최적화
  • Tree Shaking
  • concatenateModules
  • sideEffects
  • 코드 분할
  • 다중 입구 패키지
  • 동적 가져오기
  • MiniCssExtractPlugin
  • OptimizeCssAssetsWebpackPlugin
  • 출력 파일 이름 Hash

  • 개발 환경 설정


    webpack-dev-server


    웹pack-dev-server 통합 자동 컴파일링 및 브라우저 자동 리셋 등 기능npx webpack-dev-server - 자동 컴파일링 패키지 및 패키지 결과를 메모리에 저장npx webpack-dev-server --open - 패키지 결과를 자동으로 컴파일하고 패키지 결과를 메모리에 저장하고 http 서버를 시작하여 브라우저를 엽니다.

    devServer 설정 정적 자원 서버 경로 지정

    module.exports = {
         
      devServer: {
         
        contentBase: './public'
      }
    }
    

    프록시 서비스를 설정하여 개발 환경 인터페이스의 크로스 필드 문제를 해결하다

    module.exports = {
         
      devServer: {
         
        contentBase: './public',
        proxy: {
         
          //  : 
          '/api': {
         
            // http://localhost:8080/api/users -> https://api.github.com/api/users
            target: 'https://api.github.com',
            //   localhost:8080   GitHub  
            changeOrigin: true, //    
            // http://localhost:8080/api/users -> https://api.github.com/users
            pathRewrite: {
         
              '^/api': ''
            }
          }
        }
      }
    }
    

    Source Map 구성


    sourceMap 파일은 변환된 코드와 원본 코드 간의 관계를 비추어 디버깅 응용 프로그램에서 오류를 보고하여 위치를 정할 수 없는 문제를 해결했습니다.변환된 코드 파일의 마지막 줄에 자동으로 주석을 추가합니다. //# sourceMappingURL=jquery.min.map 설정 방식: webpack.config.js 증가devtool:'source-map 웹 팩은 12가지sourceMap 방식을 지원하며 효율과 효과는 각각 다릅니다.구체적인 선택 규칙:
  • 개발 모델: cheap-module-eval-source-map
  • 생산 환경: none 또는nosources-source-map 상세 정보 참조 홈페이지 source-map
  • HMR — Hot Module Replacement


    파일을 수정한 후에 다시 포장한 후에 자동으로 브라우저를 갱신하면 페이지에 있는 정보가 갱신됩니다 (입력 상자의 데이터)

    사용법


    webpack.config.js에서 구성 추가:
    module.exports = {
         
      devServer: {
         
        hot: true
      },
      plugins: [
        new webpack.HotModuleReplacementPlugin()
      ]
    }
    

    HMR 고려사항

  • HMR의 코드 오류를 처리하면 자동 리셋이 발생합니다. 해결 방법: hotOnly: true 대체hot: true
  • HMR을 사용하지 않은 경우 HMR API가 잘못되었습니다.module.hot 방법은 HMR 플러그인이 제공한 것으로 HMR을 켜지 않으면 오류가 발생한다. Cannot read property 'accept' of undefined.그래서 사용하기 전에 빈값 판단을 해야 한다. if (module.hot) { // ... } HMR을 켜지 않으면 위의 코드는 웹팩을 통해 포장된 후에 다음과 같이 변한다.
  • if (false) {
         }
    

    다중 환경 구성


    두 가지 방법:
  • 환경에 따라 구성 파일 내보내기
  • 하나의 환경은 하나의 프로필에 대응한다.

  • 환경에 따라 다양한 구성 내보내기


    프로필은 함수를 내보내고 프로필 대상을 되돌려줍니다.함수 수신 두 개의 매개 변수:cli를 통해 전달된 환경명 매개 변수env,cli를 실행하는 과정에서 전달된 모든 매개 변수argv
    module.exports = (env, argv) => {
         
      const config = {
         
        mode: 'none',
        entry: './src/main.js',
        devtool: 'source-map',
        output: {
         
          filename: 'bundle.js',
          path: path.join(__dirname, 'dist/')
        },
        module: {
         
          rules: [
            {
         
              test: /.js$/,
              use: {
         
                loader: 'babel-loader',
                options: {
         
                  presets: ['@babel/preset-env']
                }
              }
            },
            {
         
              test: /.css$/,
              use: [
                'style-loader',
                'css-loader'
              ]
            },
            {
         
              test: /.png$/,
              use: {
         
                loader: 'url-loader',
                options: {
         
                  limit: 10 * 1024
                }
              }
            }
          ]
        },
        plugins: [
          new CleanWebpackPlugin(),
          new HtmlWebpackPlugin({
         
            template: './src/index.html'
          })
        ]
      }
    
      if (env === 'production') {
         
        config.mode = 'production',
        config.devtool = 'nosources-source-map',
        config.plugins = [
          ...config.plugins,
          new CleanWebpackPlugin(),
          new CopyWebpackPlugin(['public'])
        ]
      }
      return config
    }
    

    하나의 환경은 하나의 프로필에 대응한다

    webpack.dev.js//개발환경설정webpack.prod.js//생산환경설정은 공통 프로필을 webpack.common.js에 추출하여 웹pack-merge로 통합하여 구성합니다.
    // webpack.prod.js
    const merge = require('webpack-merge');
    const common = require('./webpack.common.js');
    
    module.exports = merge(common, {
         
      mode: 'production'
    })
    

    DefinePlugin


    코드에 전역 구성원을 주입하기 위해 코드의 동명 변수 구성원을 직접 교체합니다. 프로덕션 모드에서 DefinePlugin은 기본적으로 사용되고 코드에 주입됩니다process.env.NODE_ENV.

    예제


    API_ 선언BASE_URL
    const webpack = require('webpack');
    
    module.exports = {
         
      plugins: [
        new webpack.DefinePlugin({
         
          API_BASE_URL: '"https://api.example.com"',//DefinePlugin   JavaScript  
          //API_BASE_URL: JSON.stringify('https://api.example.com'), //  , API_BASE_URL 
          PARAMS: {
          //  
            name: 'zs',
            age: 20
          },
          NUMBER: 30, //  
          BOOLEAN: true, // Boolean
          FUNC: function() {
         
            console.log('func')
          }
        })
      ]
    }
    

    포장 후:
    console.log("https://api.example.com");
    const params = Object({
         "name":zs,"age":20});
    const number = 30;
    const boolean = true;
    const func = (function() {
         
            console.log('func')
          });
    

    웹팩 최적화


    Tree Shaking


    불필요한 코드를 제거하고 생산 환경을 최적화하는 코드.생산 모드에서 자동으로 Tree-shaking을 켜는 것은 특정한 설정 옵션이 아니라 기능 조합 사용 후의 최적화 효과입니다. 비생산 모드에서 Tree Shaking을 켜고optimization을 통해 설정 옵션optimization: 웹 팩 최적화 기능을 집중적으로 설정하는 옵션입니다.
    module.exports = {
         
      optimization: {
         
        usedExports: true, //  
        minimize: true //  
      }
    }
    

    tree-shaking은 ES Module의 모듈 코드를 처리하는 것이고 babel의 일부 기능은 ES Module를 CommonJS로 바꾸어 tree-shaking의 실효를 초래할 수 있습니다.preset-env 설정을 통해 해결할 수 있습니다.
    odule.exports = {
         
      module: {
         
        rules: [
          {
         
            test: /.js$/,
            use: {
         
              loader: 'babel-loader',
              options: {
         
                // presets: ['@babel/preset-env']
                presets: [
                  //  
                  // ===============     ESModule   CommonJS 
                  ['@babel/preset-env', {
          modules: false }]
                ]
              }
            }
          }
        ]
      }
    }
    

    concatenateModules


    가능한 한 모든 모듈을 하나의 함수에 통합하여 출력하면 운행 효율을 높일 뿐만 아니라 코드의 부피도 줄일 수 있다.
    module.exports = {
         
      optimization: {
         
        usedExports: true, //  
        concatenateModules: true,
        minimize: true //  
      }
    }
    

    sideEffects


    sideEffects란 모듈이 실행될 때 구성원을 내보내는 것 외에 다른 일을 말한다. 예를 들어
    // components/index.js
    
    export {
          default as Button } from './button.js';
    export {
          default as Link } from './link.js';
    export {
          default as Header } from './header.js';
    

    위의 코드는 모듈만 내보냈을 뿐 다른 일은 하지 않았다
    // main.js
    
    //   index.js   Button  ,
    //   index.js  ,
    //  
    import {
          Button } from './components/index.js';
    

    최적화 옵션에서sideEffects를true로 설정하면 웹팩은 현재 프로젝트의 패키지를 검사합니다.json 파일에sideEffects 필드가 있는지 확인하여 모듈에 부작용이 있는지 판단합니다. 부작용이 없으면 사용하지 않은 모듈은 포장되지 않습니다.
    //webpack.config.js
    module.exports = {
         
      optimization: {
         
        //  
        sideEffects: true,
      }
    }
    
    //package.json 
    {
         
      "sideEffects": false //  
    }
    

    sideEffects를 사용하려면 코드에 정말 부작용 코드가 없는지 확인해야 한다. 위의 설정 방식이 전체적인 것이고 실제 개발에서 전체 프로젝트에 부작용 코드가 없는지 확인해야 한다. 예를 들어 제3자 플러그인의 사용 등이다. 그래서 가장 좋은 방법은 부작용 검사의 범위를 지정하는 것이다(모듈)
    //package.json
    {
         
      "sideEffects": [
        "./src/extends.js",
        "*.css"
      ]// 
    }
    

    코드 분할


    모든 모듈을 함께 포장하면 번들을 초래할 수 있습니다.js가 너무 커서 패키지가 필요합니다. 필요에 따라 불러옵니다.

    다중 입구 패키지


    다중 입구 패키지는 일반적으로 다중 페이지 응용 프로그램에 적용되며, 한 페이지는 하나의 패키지 입구와 대응하고, 공공 부분은 함께 패키지를 추출한다.
  • entry를 대상으로 설정합니다. (수조라면 여러 개의 파일을 한데 묶는 것입니다.)
  • module.exports = {
         
      entry: {
         
        index: './src/index.js',
        album: './src/album.js'
      },
      output: {
         
        // [name]  ,  entry  
        filename: '[name].bundle.js'
      }
    }
    
  • html 파일에 대응하는bundle만 도입합니다.jsHtmlWebpackPlugin는 기본적으로 모든 패키지 결과를 주입하는 html를 생성합니다.html에서 사용하는bundle를 지정하려면chunks 속성
  • 을 사용할 수 있습니다
    module.exports = {
         
      plugins: [
        new HtmlWebpackPlugin({
         
          template: './src/index.html'
          filename: 'index.html',
          chunks: ['index']
        })
        new HtmlWebpackPlugin({
         
          template: './src/album.html'
          filename: 'album.html',
          chunks: ['album']
        })
      ]
    }
    
  • 추출 공공 모듈은 서로 다른 모듈에 인용된 공공 모듈, 예를 들어 vue, jQuery, 그들을 추출하여 단독 파일에 넣고 웹팩의optimization 옵션을 사용하는 splitChunks 속성 설정
  • module.exports = {
         
      optimization: {
         
        splitChunks: {
         
          chunks: 'all' //   bundle  
          cacheGroups: {
         
            //  
            commons: {
         
              name: 'commons'
            }
          }
        }
      },
      plugins: [
        new CleanWebpackPlugin(),
        new HtmlWebpackPlugin({
         
          title: 'index',
          filename: 'index.html',
          template: './src/index.html',
          chunks: ['index', 'commons'] // commons  
        }),
        new HtmlWebpackPlugin({
         
          title: 'album',
          filename: 'album.html',
          template: './src/album.html',
          chunks: ['album', 'commons'] // commons  
        })
      ]
    }
    

    동적 가져오기


    어떤 모듈을 사용해야 할 때 이 모듈을 다시 불러옵니다.동적으로 가져오는 모듈은 자동으로 패키지화됩니다.
    // ES Modules  
    import('./posts/posts').then(module => {
         
      // TODO:  
    });
    
    //    , 
    import('./posts/posts').then(({
          default: posts }) => {
         
      // TODO:  
    });
    

    MiniCssExtractPlugin


    단독 파일로 css 추출 (일반적으로 css 파일이 150KB 이상이어야 사용)
    module.exports = {
         
      plugins: [
        new MiniCssExtractPlugin()
      ]
    }
    

    이 플러그인은 css를 단독 모듈로 추출할 수 있기 때문에style-loader에 사용할 필요가 없습니다. 대신 이 플러그인이 제공하는loader를 사용합니다.
    module: {
         
      rules: [
        {
         
          test: /.css$/,
          use: [
            // 'style-loader', //   style  
            MiniCssExtractPlugin.loader,
            'css-loader',
          ]
        }
      ]
    }
    

    OptimizeCssAssetsWebpackPlugin


    리소스 파일 압축
  • plugins 그룹에 설정
  • //webpack.config.js
    module.exports = {
         
    //...,other config
      plugins: [
      //...,
        new OptimizeCssAssetsWebpackPlugin()
      ]
    }
    
  • optimization에 설정됩니다.minimizer 수조에서 minimize 옵션으로 제어되지만, 이렇게 하면 원래의 압축기를 덮어쓰고 js의 압축 기능을 사용할 수 없습니다
  • module.exports = {
         
      optimization: {
         
        minimizer: [
          new OptimizeCssAssetsWebpackPlugin()
        ]
      }
    }
    

    출력 파일 이름 Hash


    리소스 파일 업데이트를 해결하기 위해 브라우저 캐시 문제 (파일 이름 hash의 길이를 제어하는 [contenthash:8]) 에는 다음과 같은 몇 가지 사용 방법이 있습니다.
  • [name]-[hash].bundle.js가 임의의 파일을 변경하면 모든 파일의 파일 이름이 변경됩니다
  • [name]-[chunkhash].bundle.js 같은 길의 포장,chunkhash는 모두 같다.예를 들어 다중 입구 설정 파일, 수요에 따라 모듈을 도입한다.moduleA를 변경합니다.js, 포장 후 대응하는 파일 이름이 바뀌고 다른 것은 바뀌지 않습니다.
  • [name]-[contenthash].bundle.js는 파일이 출력한 내용에 따라 생성된hash, 파일마다 다른hash
  • 좋은 웹페이지 즐겨찾기