Printable

Migrate

이 섹션에서는 이전 버전의 webpack에서 최신 버전으로 마이그레이션하는 방법을 제공합니다.

To v5 from v4

이 가이드는 webpack을 직접 사용할 때 webpack 5로 마이그레이션 하는 데 도움이 되는 것을 목표로 합니다. webpack을 실행하기 위해 더 높은 수준의 도구를 사용하는 경우 그 도구의 마이그레이션 지침을 참고하세요.

Preparations

Webpack 5는 Node.js 10.13.0 (LTS) 이상의 버전이 필요합니다. 따라서 여전히 이전 버전을 실행 중인 경우 Node.js를 업그레이드해야 합니다.

Upgrade webpack 4 and its plugins/loaders

  1. webpack 4의 사용 가능한 최신 버전으로 업그레이드하세요.

    • webpack >= 4를 사용하는 경우 최신 webpack 4 버전으로 업그레이드할 때 추가 지침이 필요하지 않습니다.

    • webpack 버전 4 미만을 사용하는 경우 webpack 4 마이그레이션 가이드를 참고하세요.

  2. webpack-cli 을 사용한다면 사용 가능한 최신 버전으로 업그레이드하세요.

  3. 사용한 모든 플러그인과 로더를 사용 가능한 최신 버전으로 업그레이드하세요.

    일부 플러그인 또는 로더에는 webpack 5와 호환되기 위해 사용해야 하는 베타 버전이 있을 수 있습니다. 최신 버전이 webpack 5만 지원할 수 있고, 이때 v4에서는 실패할 수 있으므로 업그레이드할 때는 개별 플러그인과 로더의 릴리스 정보를 읽어보세요. 이 경우 webpack 4를 지원하는 최신 버전으로 업데이트 하는 것을 권장합니다.

Make sure your build has no errors or warnings

webpack, webpack-cli, 플러그인 그리고 로더를 업그레이드하면서 새로운 오류와 경고가 있을 수 있습니다. 빌드 중 사용 중단 경고를 주시하세요.

이 방법으로 webpack을 호출하여 어떤 플러그인과 로더가 책임이 있는지 파악하기 위해 사용 중단 경고에 대한 스택 추적을 얻을 수 있습니다.

node --trace-deprecation node_modules/webpack/bin/webpack.js

webpack 5는 이제는 사용되지 않는 기능을 모두 제거하므로 계속 진행하려면 빌드 중에 webpack 사용 중단 경고가 없는지 확인하세요.

Make sure to use mode

modeproduction 또는 develop으로 설정하여 해당 기본값이 설정되어 있는지 확인하세요.

Update outdated options

다음 옵션을 새 버전으로 업데이트합니다. (사용되는 경우)

  • optimization.hashedModuleIds: trueoptimization.moduleIds: 'hashed'
  • optimization.namedChunks: trueoptimization.chunkIds: 'named'
  • optimization.namedModules: trueoptimization.moduleIds: 'named'
  • NamedModulesPluginoptimization.moduleIds: 'named'
  • NamedChunksPluginoptimization.chunkIds: 'named'
  • HashedModuleIdsPluginoptimization.moduleIds: 'hashed'
  • optimization.noEmitOnErrors: falseoptimization.emitOnErrors: true
  • optimization.occurrenceOrder: trueoptimization: { chunkIds: 'total-size', moduleIds: 'size' }
  • optimization.splitChunks.cacheGroups.vendorsoptimization.splitChunks.cacheGroups.defaultVendors
  • optimization.splitChunks.cacheGroups.test(module, chunks)optimization.splitChunks.cacheGroups.test(module, { chunkGraph, moduleGraph })
  • Compilation.entriesCompilation.entryDependencies
  • serveDevServer를 위해 serve가 제거되었습니다.
  • Rule.query (v3부터 사용 중단됨) → Rule.options/UseEntry.options
  • Rule.loadersRule.use

Test webpack 5 compatibility

webpack 4 설정에서 다음 옵션을 설정하고 빌드가 여전히 올바르게 작동하는지 확인하세요.

module.exports = {
  // ...
  node: {
    Buffer: false,
    process: false,
  },
};

webpack 5의 설정을 업그레이드할 때 이 옵션을 다시 제거해야 합니다.

Upgrade webpack to 5

이제 webpack을 버전 5로 업그레이드해 봅시다.

  • npm: npm install webpack@latest

  • Yarn: yarn add webpack@latest

Webpack 4 및 해당 플러그인/로더 업그레이드 단계에서 일부 플러그인/로더를 최신 버전으로 업그레이드할 수 없는 경우, 지금 잊지 말고 업그레이드하세요.

Clean up configuration

  • webpack 설정에서 optimization.moduleIdsoptimization.chunkIds 제거를 고려하세요. 기본값은 production 모드에서 장기 캐싱을 지원하고 development 모드에서 디버깅을 지원하기 때문에 더 나을 수 있습니다.

  • webpack 설정에서 [hash] placeholder를 사용할 때 [contenthash]로 변경하는 것이 좋습니다. 동일하지는 않지만, 더 효과적인 것으로 입증되었습니다.

  • Yarn의 PnP 및 pnp-webpack-plugin을 사용하는 경우 좋은 소식이 있습니다. 이제 기본적으로 지원됩니다. 설정에서 제거해야 합니다.

  • 정규 표현식과 함께 IgnorePlugin을 인수로 사용하는 경우 이제 options object를 사용합니다. new IgnorePlugin({ resourceRegExp: /regExp/ }).

  • node.fs: 'empty'와 같은 것을 사용하는 경우 resolve.fallback.fs: false로 교체하세요.

  • webpack Node.js API에서 watch: true를 사용하는 경우 제거하세요. 호출하는 컴파일러 메서드가 나타내는 대로 설정할 필요가 없습니다. watch()의 경우 true 또는 run()의 경우 false 입니다.

  • raw-loader, url-loader 또는 file-loader를 사용하여 애셋들을 load 하기 위해 정의된 rules가 있는 경우 가까운 장래에 사용되지 않을 것이므로 Asset Modules 을 대신 사용하세요.

  • target이 함수로 설정되어 있으면 false로 업데이트하고 plugins option 내에서 해당 함수를 적용하세요. 아래 예를 참고하세요.

    // for webpack 4
    {
        target: WebExtensionTarget(nodeConfig)
    }
    
    // for webpack 5
    {
        target: false,
        plugins: [
            WebExtensionTarget(nodeConfig)
        ]
    }
  • output.library 또는 output.libraryTarget이 정의된 경우 속성 이름을 변경합니다 (output.libraryTarget -> output.library.type, output.library -> output.library.name). 예를 들면 다음과 같습니다.

    // for webpack 4
    {
        output: {
          library: 'MyLibrary',
          libraryTarget: 'commonjs2'
        }
    }
    
    // for webpack 5
    {
        output: {
          library: {
            name: 'MyLibrary',
            type: 'commonjs2'
          }
        }
    }

import를 통해 WebAssembly를 사용하는 경우 다음 두 단계 프로세스를 따라야 합니다.

  • webpack 4에서와 동일한 동작을 얻으려면 experiments.syncWebAssembly: true를 설정하여 이제는 사용되지 않는 사양을 활성화합니다.
  • webpack 5로 성공적으로 마이그레이션 한 후 WASM 통합을 위한 최신 사양을 사용하려면 experiments 값을 experiments: { asyncWebAssembly: true }으로 변경합니다.

optimization.splitChunks 를 재고하세요.

  • 기본값 또는 optimization.splitChunks: { chunks: 'all' }을 사용하는 것을 권장합니다.
  • 사용자 정의 설정을 사용할 때 name: false를 삭제하고 name: string | functionidHint: string | function로 교체하세요.
  • Optimization.splitChunks.cacheGroups: { default: false, vendors: false }를 설정하여 기본값을 끌 수 있었습니다. 이것을 권장하지 않지만, webpack 5에서 같은 효과를 얻고 싶다면 optimization.splitChunks.cacheGroups: { default: false, defaultVendors: false }를 사용할 수 있습니다.

기본값 제거를 고려하세요.

  • entry: './src/index.js'는 생략할 수 있습니다. 이것이 기본값입니다.
  • output.path: path.resolve(__dirname, 'dist')는 생략할 수 있습니다. 이것이 기본값입니다.
  • output.filename: '[name].js'는 생략할 수 있습니다. 이것이 기본값입니다.

Need to support an older browser like IE 11?

  • 프로젝트에 대해 browserslist를 활성화한 경우 webpack 5는 browserslist 설정을 재사용하여 런타임 코드에 대해 내보낼 코드 스타일을 결정합니다.

    확실히 할 것들.

    1. targetbrowserslist으로 설정하거나 webpack이 자동으로 browserslist을 설정하도록 target을 제거합니다.
    2. IE 11을 browserslist 설정에 추가합니다.
  • browserslist가 없으면 webpack의 런타임 코드는 ES2015 구문(예: 화살표 함수)을 사용하여 더 작은 번들을 빌드합니다. 따라서 ES2015 구문을 지원하지 않는 브라우저(예: IE11)에 ES5 구문을 사용하려면 target: ['web', 'es5']를 설정해야 합니다.

  • Node.js의 경우 빌드에는 target option에 지원되는 Node.js 버전이 포함되며 webpack은 지원되는 구문을 자동으로 파악합니다. 예를 들어 target: 'node8.6'와 같이 사용합니다.

Cleanup the code

Using /* webpackChunkName: '...' */

사용 의도를 이해해야 합니다.

  • 여기서 chunk's name은 public 용입니다.
  • 오직 개발을 위한 이름이 아닙니다.
  • Webpack은 이를 사용하여 production 및 development 모드에서 파일 이름을 지정합니다.
  • Webpack 5는 webpackChunkName을 사용하지 않는 경우에도 development 모드에서 유용한 파일 이름을 자동으로 할당합니다.

Using named exports from JSON modules

이것은 새 사양에서 지원되지 않으며 경고가 표시됩니다.

import { version } from './package.json';
console.log(version);

위 코드 대신 아래 코드를 사용하세요.

import pkg from './package.json';
console.log(pkg.version);

Cleanup the build code

  • const compiler = webpack(...);을 사용할 때 컴파일러를 사용한 후에는 반드시 컴파일러를 닫아야 합니다. compiler.close(callback);.
    • 이것은 자동으로 닫히는 webpack(..., callback) 양식에는 적용되지 않습니다.
    • 사용자가 프로세스를 종료할 때까지 감시 모드에서 webpack을 사용하는 경우 선택 사항입니다. 이런 종류의 작업에는 감시 모드의 유휴 단계가 사용됩니다.

Run a single build and follow advice

빌드 오류/경고를 주의 깊게 읽어보세요. 해당하는 조언이 없는 경우 issue를 생성해 주시면 해결해 드리겠습니다.

최소한 레벨 3 또는 4를 풀 때까지 다음 단계를 반복합니다.

  • Level 1: Schema validation fails.

    Configuration options가 변경되었습니다. BREAKING CHANGE: 메모 또는 대신 사용해야 하는 옵션에 대한 힌트에 유효성 검사 오류가 있어야 합니다.

  • Level 2: Webpack exits with an error.

    오류 메시지는 변경해야 할 사항을 알려야 합니다.

  • Level 3: Build Errors.

    오류 메시지에는 BREAKING CHANGE: 메모가 있어야 합니다.

  • Level 4: Build Warnings.

    경고 메시지는 무엇을 개선할 수 있는지 알려야 합니다.

  • Level 5: Runtime Errors.

    이것은 까다롭습니다. 문제를 찾으려면 디버그해야 할 것입니다. 일반적인 조언은 여기에서 어렵습니다. 그러나 런타임 오류와 관련하여 아래에 몇 가지 일반적인 조언을 나열합니다.

    • process는 정의되지 않았습니다.
      • webpack 5는 더 이 Node.js 변수에 대한 폴리필을 포함하지 않습니다. 프론트엔드 코드에서 사용하지 마세요.
      • 브라우저 사용을 지원하고 싶으신가요? 환경에 따라 다른 코드를 사용하려면 export 또는 imports package.json 필드를 사용하세요.
        • 또한 이전 번들러를 지원하려면 browser 필드를 사용합니다.
        • 대안: typeof process 검사로 코드 블록을 래핑 합니다. 이는 번들 크기에 부정적인 영향을 미칩니다.
      • process.env.VARIABLE과 함께 환경 변수를 사용하고 싶으신가요? 설정에서 이러한 변수를 정의하려면 DefinePlugin 또는 EnvironmentPlugin을 사용해야 합니다.
        • 그것 대신 VARIABLE 사용을 고려하고 typeof VARIABLE !== 'undefined'도 확인하세요. process.env는 Node.js에 따라 다르며 프론트엔드 코드에서는 피해야 합니다.
    • auto가 포함된 URL을 가리키는 404 오류
      • 모든 생태계 도구가 output.publicPath: "auto"를 통한 새로운 기본 자동 publicPath에 대해 준비된 것은 아닙니다
        • 대신 고정값 output.publicPath: ""를 사용하세요.
  • Level 6: Deprecation Warnings.

    사용 중단 경고가 많을 수 있습니다. 이것은 직접적인 문제가 아닙니다. 플러그인은 핵심 변경 사항을 따라잡을 시간이 필요합니다. 이러한 지원 중단을 플러그인에 보고하세요. 이러한 지원 중단은 경고일 뿐이며 빌드는 여전히 약간의 단점(예: 성능 저하)으로만 작동합니다.

    • --no-deprecation 플래그와 함께 node를 실행하여 사용 중단 경고를 숨길 수 있습니다(예: node --no-deprecation node_modules/webpack/bin/webpack.js). 이것은 일시적인 해결 방법일 뿐입니다.
    • 플러그인 및 로더 기여자는 사용 중단 메시지의 조언을 따라 코드를 개선할 수 있습니다.
  • Level 7: Performance issues.

    일반적으로 webpack 5에서는 성능이 향상되지만, 성능이 나빠지는 경우도 있습니다.

    그리고 상황을 개선하기 위해 다음과 같이 할 수 있습니다.

    • 시간이 어디에서 소요되었는지 설명합니다.
      • --profile --progress는 이제 간단한 성능 프로필을 표시합니다.
      • node --inspect-brk node_modules/webpack/bin/webpack.js + chrome://inspect / edge://inspect (프로파일러 탭 참고).
        • 이러한 프로필을 파일에 저장하고 이슈에 제공할 수 있습니다.
        • 어떤 경우에는 더 나은 스택 추적을 위해 --no-turbo-inlining 플래그를 사용해 보세요.
    • 증분 빌드에서 모듈을 빌드하는 시간은 webpack 4에서와 같이 안전하지 않은 캐싱으로 되돌리면 개선될 수 있습니다.
      • module.unsafeCache: true
      • 그러나 이것은 코드 기반의 일부 변경 사항을 처리하는 기능에 영향을 미칠 수 있습니다.
    • Full build
      • 이제는 사용되지 않는 기능에 대한 이전 버전과의 호환성 계층은 일반적으로 새 기능에 비해 성능이 저하됩니다.
      • 경고를 많이 생성하면 무시하더라도 빌드 성능에 영향을 줄 수 있습니다.
      • Source Maps는 비용이 많이 듭니다. 문서에서 devtool 옵션을 확인하여 다양한 옵션을 비교하세요.
      • 바이러스 백신 보호는 파일 시스템 액세스 성능에 영향을 줄 수 있습니다.
      • 영구 캐싱은 반복적인 전체 빌드를 개선하는 데 도움이 될 수 있습니다.
      • 모듈 연합을 사용하면 애플리케이션을 여러 개의 작은 빌드로 분할할 수 있습니다.

Everything works?

webpack 5로 성공적으로 마이그레이션 했다고 트윗해주세요. Tweet it

It is not working?

issue를 만들고 마이그레이션 중에 발생한 문제에 대해 알려주세요.

Something missing in this guide?

Pull Request를 만들어 이 가이드를 사용하는 다음 사람을 도와주세요.

Changes to internals

유형 추가, 코드 리팩토링 및 메서드 이름 변경과 같은 webpack 내부의 변경 사항은 관심 있는 모든 사람을 위해 여기에 나열됩니다. 그러나 일반적인 사용 사례 마이그레이션의 일부로 의도한 것은 아닙니다.

  • Module.nameForCondition, Module.updateCacheModuleModule.chunkCondition은 더 이상 선택 사항이 아닙니다.

getOptions method for Loaders

Webpack 5는 로더 컨텍스트에서 사용할 수 있는 내장 this.getOptions 메서드와 함께 제공됩니다. 이것은 이전에 선호하는 schema-utils에서 getOptions 메소드를 사용했던 로더에 대한 주요 변경 사항입니다.

  • this.getOptions는 webpack 5부터 사용할 수 있습니다.
  • JSON5 대신 쿼리 문자열로 JSON을 지원합니다. ?{arg:true}?{"arg":true}. JSON5를 사용하는 것은 해당 로더의 문서에서 이제는 사용되지 않는 것으로 간주하고 문서화되어야 합니다.
  • loader-utils에는 쿼리 문자열 구문 분석을 위한 특정 동작이 있습니다(true, falsenullstring로 구문 분석되지 않고 원시 값으로 구문 분석됨). 기본 querystring 구문 분석(Node.js와 함께 제공됨) 을 사용하는 새로운 내장 this.getOptions 메서드의 경우에는 그렇지 않습니다. this.getOptions 메소드를 사용하여 옵션을 가져온 후 로더의 코드에서 이러한 경우에 대한 사용자 정의 동작을 추가하는 것은 여전히 가능합니다.
  • 새로운 this.getOptions 메서드에 대해 스키마 인수는 선택 사항이지만 로더 옵션에 대한 스키마 유효성 검사를 추가하는 것이 좋습니다. 스키마의 title 필드는 유효성 검사 오류 메시지를 사용자 정의하는 데 사용할 수 있습니다. 예를 들면 "title": "My Loader ooptions"는 다음과 같은 방식으로 오류를 표시합니다. Invalid ooooptions object. My Loader has been initialised using an ooooptions object that does not match the API schema. - ooooptions.foo.bar.baz should be a string.

To v4 from v3

이 가이드는 최종 사용자에게 영향을 주는 주요 변경 사항들을 보여줍니다. 더 자세한 사항은 변경 사항을 참고하세요.

Node.js v4

Node.js v4 이하의 버전을 사용하고 있다면, Node.js v6 이상으로 업그레이드할 필요가 있습니다.

Node.js의 버전을 업그레이드 하기 위한 지침 사항들은 이곳에서 찾아볼 수 있습니다.

CLI

CLI는 분리된 패키지(webpack-cli)로 옮겼습니다. webpack을 사용하기 전에 CLI를 설치해야합니다. 기본 설정을 참고하세요.

설치 가이드는 이곳에서 찾을 수 있습니다.

Update plugins

대부분의 3rd party 플러그인은 webpack 4와 호환되는 최신 버전으로 업데이트 해야합니다. 잘 알려진 플러그인들에 대한 링크는 이곳에서 찾아 볼 수 있습니다.

mode

설정에 새로운 mode 옵션을 추가하세요. 설정 타입에 따라 'production', 'development' 혹은 'none'으로 설정하세요.

webpack.config.js

module.exports = {
  // ...
+  mode: 'production',
}

Deprecated/Removed plugins

이러한 플러그인은 프로덕션 모드에서 기본 제공되므로 설정에서 제거할 수 있습니다.

webpack.config.js

module.exports = {
  // ...
  plugins: [
-    new NoEmitOnErrorsPlugin(),
-    new ModuleConcatenationPlugin(),
-    new DefinePlugin({ "process.env.NODE_ENV": JSON.stringify("production") })
-    new UglifyJsPlugin()
  ],
}

이러한 플러그인은 프로덕션 모드에서 기본으로 제공됩니다.

webpack.config.js

module.exports = {
  // ...
  plugins: [
-    new NamedModulesPlugin()
  ],
}

이러한 플러그인은 더 이상 사용되지 않고, 현재는 삭제되었습니다.

webpack.config.js

module.exports = {
  // ...
  plugins: [
-    new NoErrorsPlugin(),
-    new NewWatchingPlugin()
  ],
}

CommonsChunkPlugin

CommonsChunkPlugin은 삭제되었습니다. 대신 optimization.splitChunks을 사용할 수 있습니다.

더 자세한 사항은 optimization.splitChunks 문서에서 찾을 수 있습니다. 기본 설정은 이미 요구사항을 충족할 것입니다.

import() and CommonJS

non-ESM을 불러오기 위해 import()을 사용할 때, webpack 4에서 결과는 바뀝니다. 그래서 module.exports의 값을 얻기 위해 default 프로퍼티에 접근할 필요가 있습니다.

non-esm.js

module.exports = {
  sayHello: () => {
    console.log('hello world');
  },
};

example.js

function sayHello() {
  import('./non-esm.js').then((module) => {
    module.default.sayHello();
  });
}

json and loaders

.json 파일을 변환하기 위해 사용자 지정 로더를 사용할 때, type 모듈을 바꿔야 합니다.

webpack.config.js

module.exports = {
  // ...
  rules: [
    {
      test: /config\.json$/,
      loader: 'special-loader',
+     type: 'javascript/auto',
      options: {...}
    }
  ]
};

아직도 json-loader를 사용한다면, 이것을 지울 수 있습니다.

webpack.config.js

module.exports = {
  // ...
  rules: [
    {
-     test: /\.json$/,
-     loader: 'json-loader'
    }
  ]
};

module.loaders

module.loaders는 webpack 2부터 사용하지 않으며, 현재는 module.rules에 따라 삭제했습니다.

To v2 or v3 from v1

  • 다음 섹션에서는 webpack 1에서 2로의 주요 변경 사항을 설명합니다.

resolve.root, resolve.fallback, resolve.modulesDirectories

위 옵션들은 resolve.modules 로 대체되었습니다. 자세한 사용법은 resolving을 참고하세요.

  resolve: {
-   root: path.join(__dirname, "src")
+   modules: [
+     path.join(__dirname, "src"),
+     "node_modules"
+   ]
  }

resolve.extensions

이 옵션은 더 이상 빈 문자열을 전달할 필요가 없습니다. 이 동작은 resolve.enforceExtension으로 이동되었습니다. 자세한 사용법은 resolving 를 참고하세요.

resolve.*

여기에서 여러 API가 변경되었습니다. 흔히 사용되지 않으므로 자세히 나열하지 않습니다. 자세한 내용은 resolving을 참고하세요.

module.loaders is now module.rules

이전의 로더설정은 로더와 그 이상의 설정이 허가되는 강력한 규칙 시스템으로 대체 되었습니다. 호환성을 위해 이전의 module.loaders 구문은 여전히 유효하며 이전 이름은 구문 분석됩니다. 네이밍 컨벤션들이 이해하기 쉬워졌고 module.rules를 사용하도록 설정을 업그레이드 해야하는 좋은 이유입니다.

  module: {
-   loaders: [
+   rules: [
      {
        test: /\.css$/,
-       loaders: [
-         "style-loader",
-         "css-loader?modules=true"
+       use: [
+         {
+           loader: "style-loader"
+         },
+         {
+           loader: "css-loader",
+           options: {
+             modules: true
+           }
+         }
        ]
      },
      {
        test: /\.jsx$/,
        loader: "babel-loader", // Do not use "use" here
        options: {
          // ...
        }
      }
    ]
  }

Chaining loaders

webpack 1에서와 같이 로더를 연결하여 로더에서 로더로 결과를 전달할 수 있습니다. rule.use 를 사용하여, use 를 로더 배열로 설정할 수 있습니다. webpack 1에서 로더는 일반적으로 !로 연결되었습니다. 이 스타일은 레거시 옵션 module.loaders 를 사용하는 경우에만 지원됩니다.

  module: {
-   loaders: [{
+   rules: [{
      test: /\.less$/,
-     loader: "style-loader!css-loader!less-loader"
+     use: [
+       "style-loader",
+       "css-loader",
+       "less-loader"
+     ]
    }]
  }

Automatic -loader module name extension removed

로더를 참고할 때 -loader 확장자를 더 이상 생략할 수 없습니다.

  module: {
    rules: [
      {
        use: [
-         "style",
+         "style-loader",
-         "css",
+         "css-loader",
-         "less",
+         "less-loader",
        ]
      }
    ]
  }

resolveLoader.moduleExtensions 설정 옵션을 사용하여 이전 동작을 계속 선택할 수 있지만 이는 권장되지 않습니다.

+ resolveLoader: {
+   moduleExtensions: ["-loader"]
+ }

이 변경 이유는 #2986 을 참고하세요.

json-loader is not required anymore

JSON 파일에 대해 설정된 로더가 없으면, webpack은 자동으로 json-loader로 JSON 파일을 로드하려고 시도합니다.

  module: {
    rules: [
-     {
-       test: /\.json/,
-       loader: "json-loader"
-     }
    ]
  }

webpack, node.js 및 browserify 간의 환경차이를 없애기 위해 그렇게 하기로 결정했습니다.

Loaders in configuration resolve relative to context

webpack 1 에서, 설정된 로더가 일치하는 파일을 기준으로 확인되어집니다. 하지만, webpack 2 에서는, 설정된 로더는 context 옵션을 기준으로 확인됩니다.

이것은 npm link 를 사용하거나 외부 context 모듈을 참고할 때 로더에 의해 발생하는 중복 모듈 문제를 해결합니다.

이 문제를 해결하기 위해 몇 가지 핵을 제거할 수 있습니다.

  module: {
    rules: [
      {
        // ...
-       loader: require.resolve("my-loader")
+       loader: "my-loader"
      }
    ]
  },
  resolveLoader: {
-   root: path.resolve(__dirname, "node_modules")
  }

module.preLoaders and module.postLoaders were removed:

  module: {
-   preLoaders: [
+   rules: [
      {
        test: /\.js$/,
+       enforce: "pre",
        loader: "eslint-loader"
      }
    ]
  }

UglifyJsPlugin sourceMap

UglifyJsPluginsourceMap 옵션은 true 대신 false 로 기본 설정됩니다. 즉, 최소화된 코드에 소스맵을 사용하거나 uglifyjs 경고에 대한 올바른 줄 번호를 원하는 경우 UglifyJsPlugin에서 sourceMap: true를 설정해야 합니다.

  devtool: "source-map",
  plugins: [
    new UglifyJsPlugin({
+     sourceMap: true
    })
  ]

UglifyJsPlugin warnings

UglifyJsPlugincompress.warnings 옵션은 이제 true 대신 false로 기본 설정됩니다. 즉, uglifyjs 경고를 보려면 compress.warningstrue로 설정해야 합니다.

  devtool: "source-map",
  plugins: [
    new UglifyJsPlugin({
+     compress: {
+       warnings: true
+     }
    })
  ]

UglifyJsPlugin minimize loaders

UglifyJsPlugin 은 더 이상 로더를 최소화 모드로 전환하지 않습니다. minimize: true 설정은 장기적으로 로더 옵션을 통해 전달되어야 합니다. 관련 옵션은 로더 문서를 참고하세요.

로더의 최소화 모드는 webpack 3 이상에서 제거됩니다.

이전 로더와의 호환성을 유지하기 위해 플러그인을 통해 로더를 최소화 모드로 전환할 수 있습니다.

  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     minimize: true
+   })
  ]

DedupePlugin has been removed

webpack.optimize.DedupePlugin은 더 이상 필요하지 않습니다. 설정에서 제거하세요.

BannerPlugin - breaking change

BannerPlugin은 더 이상 두 개의 매개변수를 허용하지 않고 단일 옵션 개체를 허용합니다.

  plugins: [
-    new webpack.BannerPlugin('Banner', {raw: true, entryOnly: true});
+    new webpack.BannerPlugin({banner: 'Banner', raw: true, entryOnly: true});
  ]

OccurrenceOrderPlugin is now on by default

OccurrenceOrderPlugin은 이제 기본적으로 활성화되며 이름이 변경되었습니다(webpack 1의 OccurenceOrderPlugin). 따라서 설정에서 플러그인을 제거해야 합니다.

  plugins: [
    // webpack 1
-   new webpack.optimize.OccurenceOrderPlugin()
    // webpack 2
-   new webpack.optimize.OccurrenceOrderPlugin()
  ]

ExtractTextWebpackPlugin - breaking change

ExtractTextPlugin 이 webpack 2와 함께 작동하려면 버전 2가 필요합니다.

npm install --save-dev extract-text-webpack-plugin

이 플러그인의 설정 변경은 주로 구문입니다.

ExtractTextPlugin.extract

module: {
  rules: [
    {
      test: /.css$/,
-      loader: ExtractTextPlugin.extract("style-loader", "css-loader", { publicPath: "/dist" })
+      use: ExtractTextPlugin.extract({
+        fallback: "style-loader",
+        use: "css-loader",
+        publicPath: "/dist"
+      })
    }
  ]
}

new ExtractTextPlugin({options})

plugins: [
-  new ExtractTextPlugin("bundle.css", { allChunks: true, disable: false })
+  new ExtractTextPlugin({
+    filename: "bundle.css",
+    disable: false,
+    allChunks: true
+  })
]

Full dynamic requires now fail by default

표현식(즉, require(expr))만 있는 종속성은 이제 전체 디렉터리의 컨텍스트 대신 빈 컨텍스트를 생성합니다.

이와 같은 코드는 ES2015 모듈에서 작동하지 않으므로 리팩토링해야 합니다. 이것이 가능하지 않다면 ContextReplacementPlugin을 사용하여 컴파일러가 올바른 해결을 하도록 힌트를 줄 수 있습니다.

Using custom arguments in CLI and configuration

CLI를 남용하여 다음과 같이 설정에 사용자 지정 인수를 전달한 경우.

webpack --custom-stuff

// webpack.config.js
var customStuff = process.argv.indexOf('--custom-stuff') >= 0;
/* ... */
module.exports = config;

이것이 더 이상 허용되지 않음을 알 수 있습니다. 이제 CLI가 더 엄격해졌습니다.

대신 설정에 인수를 전달하기 위한 인터페이스가 있습니다. 대신 사용해야 합니다. 미래의 도구는 이것에 의존할 수 있습니다.

webpack --env.customStuff

module.exports = function (env) {
  var customStuff = env.customStuff;
  /* ... */
  return config;
};

CLI를 참고하세요.

require.ensure and AMD require are asynchronous

이러한 함수는 이제 청크가 이미 로드된 경우 동기식으로 콜백을 호출하는 대신 항상 비동기식입니다.

require.ensure는 이제 네이티브 Promise에 의존합니다. 그것들이 없는 환경에서 require.ensure를 사용한다면 폴리필이 필요할 것입니다.

Loader configuration is through options

webpack.config.js에서 사용자 정의 속성으로 로더를 더 이상 설정할 수없습니다. options을 통해 수행해야 합니다. ts 속성이 있는 다음 설정은 더 이상 webpack 2에서 유효하지 않습니다.

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
      },
    ],
  },
  // does not work with webpack 2
  ts: { transpileOnly: false },
};

What are options?

좋은 질문입니다. 엄밀히 말하면 2가지로 해석 가능하며, 모두 webpack 로더를 설정하는 방법입니다. 고전적으로 optionsquery라고 했으며 로더 이름에 추가할 수 있는 문자열이었습니다. 쿼리 문자열과 매우 유사하지만 실제로는 더 강력한 기능입니다.

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader?' + JSON.stringify({ transpileOnly: false }),
      },
    ],
  },
};

그러나 로더와 함께 제공되는 별도로 지정된 객체일 수도 있습니다.

module.exports = {
  //...
  module: {
    rules: [
      {
        test: /\.tsx?$/,
        loader: 'ts-loader',
        options: { transpileOnly: false },
      },
    ],
  },
};

LoaderOptionsPlugin context

일부 로더는 컨텍스트 정보가 필요하고 설정에서 이를 읽습니다. 이것은 장기적으로 로더 옵션을 통해 전달되어야 합니다. 관련 옵션은 로더 문서를 참고하세요.

이전 로더와의 호환성을 유지하기 위해 플러그인을 통해 이 정보를 전달할 수 있습니다.

  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     options: {
+       context: __dirname
+     }
+   })
  ]

debug

debug 옵션은 webpack 1에서 로더를 디버그 모드로 전환했습니다. 이것은 장기적으로 로더 옵션을 통해 전달되어야 합니다. 관련 옵션은 로더 문서를 참고하세요.

로더의 디버그 모드는 webpack 3 이상에서 제거됩니다.

이전 로더와의 호환성을 유지하기 위해 플러그인을 통해 로더를 디버그 모드로 전환할 수 있습니다.

- debug: true,
  plugins: [
+   new webpack.LoaderOptionsPlugin({
+     debug: true
+   })
  ]

Code Splitting with ES2015

webpack 1에서는 require.ensure() 를 응용 프로그램의 청크를 지연 로드하는 방법으로 사용할 수 있습니다.

require.ensure([], function (require) {
  var foo = require('./module');
});

ES2015 로더 사양은 import()를 런타임에 동적으로 ES2015 모듈을 로드하는 방법으로 정의합니다. Webpack은 import()를 분리점으로 처리하고 요청된 모듈을 별도의 청크에 넣습니다. import()는 모듈 이름을 인수로 취하고 Promise를 반환합니다.

function onClick() {
  import('./module')
    .then((module) => {
      return module.default;
    })
    .catch((err) => {
      console.log('Chunk loading failed');
    });
}

좋은 소식: 청크 로드 실패는 Promise 기반이기 때문에 이제 처리할 수 있습니다.

Dynamic expressions

부분 표현식을 import()에 전달할 수 있습니다. 이것은 CommonJS의 표현식과 유사하게 처리됩니다(webpack은 가능한 모든 파일과 함께 context을 생성합니다).

import()는 가능한 각 모듈에 대해 별도의 청크를 생성합니다.

function route(path, query) {
  return import(`./routes/${path}/route`).then(
    (route) => new route.Route(query)
  );
}
// This creates a separate chunk for each possible route

Mixing ES2015 with AMD and CommonJS

AMD 및 CommonJS의 경우 세 가지 모듈 유형을 모두 자유롭게 혼합할 수 있습니다(동일한 파일 내에서도). 이 경우 Webpack은 babel 및 node-eps와 유사하게 동작합니다.

// CommonJS consuming ES2015 Module
var book = require('./book');

book.currentPage;
book.readPage();
book.default === 'This is a book';
// ES2015 Module consuming CommonJS
import fs from 'fs'; // module.exports map to default
import { readFileSync } from 'fs'; // named exports are read from returned object+

typeof fs.readFileSync === 'function';
typeof readFileSync === 'function';

Webpack이 사용할 수 있도록 이러한 모듈 기호를 구문 분석하지 않도록 Babel에 지시하는 것이 중요합니다. .babelrc 또는 babel-loader 옵션에서 다음을 설정하면 됩니다.

.babelrc

{
  "presets": [["es2015", { "modules": false }]]
}

Hints

무언가를 바꿀 필요는 없지만 기회입니다.

Template strings

Webpack은 이제 표현식에서 템플릿 문자열을 지원합니다. 이는 Webpack 설정에서 사용할 수 있음을 의미합니다.

- require("./templates/" + name);
+ require(`./templates/${name}`);

Configuration Promise

Webpack은 이제 설정 파일에서 Promise 반환을 지원합니다. 이렇게 하면 설정 파일에서 비동기 처리가 가능합니다.

webpack.config.js

module.exports = function () {
  return fetchLangs().then((lang) => ({
    entry: '...',
    // ...
    plugins: [new DefinePlugin({ LANGUAGE: lang })],
  }));
};

Advanced loader matching

Webpack은 이제 로더에 대해 일치시킬 더 많은 항목을 지원합니다.

module.exports = {
  //...
  module: {
    rules: [
      {
        resource: /filename/, // matches "/path/filename.js"
        resourceQuery: /^\?querystring$/, // matches "?querystring"
        issuer: /filename/, // matches "/path/something.js" if requested from "/path/filename.js"
      },
    ],
  },
};

More CLI options

사용할 수 있는 몇 가지 새로운 CLI 옵션이 있습니다.

--define process.env.NODE_ENV="production" DefinePlugin를 참고하세요.

--display-depth 는 각 모듈의 진입점까지의 거리를 표시합니다.

--display-used-exports 는 모듈에서 사용되는 내보내기 정보를 표시합니다.

--display-max-modules 는 출력에 표시되는 모듈의 수를 설정합니다(기본값은 15).

-p는 이제 process.env.NODE_ENV"production"으로 정의합니다.

Loader changes

변경 사항은 로더 작성자에게만 해당됩니다.

Cacheable

이제 기본적으로 로더를 캐시할 수 있습니다. 로더는 캐시할 수 없는 경우 옵트아웃해야 합니다.

  // Cacheable loader
  module.exports = function(source) {
-   this.cacheable();
    return source;
  }
  // Not cacheable loader
  module.exports = function(source) {
+   this.cacheable(false);
    return source;
  }

Complex options

webpack 1 은 로더에 대해 JSON.stringify 가능 옵션만 지원합니다.

webpack 2 는 이제 모든 JS 개체를 로더 옵션으로 지원합니다.

webpack 2.2.1 이전(즉, 2.0.0에서 2.2.0까지), ident를 사용하는 데 필요한 복잡한 옵션을 사용하여 options 객체를 사용하여 다른 로더에서 참고할 수 있습니다. 이는 2.2.1에서 제거되었으므로 현재 마이그레이션에서는 ident 키를 사용할 필요가 없습니다.

{
  test: /\.ext/
  use: {
    loader: '...',
    options: {
-     ident: 'id',
      fn: () => require('./foo.js')
    }
  }
}

1 Contributor

webpack