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')
    }
  }
}

14 Contributors

sokrajhnnsgrgurdomfarolinojohnnyreillyjouni-kantolafrederikprijckchrisVillanuevabebrawhowdy39selbekkndelangenEugeneHlushkobyzyk

Translators