webpack4でビルドしたときにエラーになる

■前提

webpack初心者

■本題

qiita.com

もともとはこの記事にしたがってVue.jsを勉強してて、

qiita.com

この記事にしたがって、Sassをビルドしようとした

するとこのコマンドでビルドしようとしたらエラーになった

$ webpack --watch --progress
tkfric:Sample tkfric$ webpack --watch --progress
Invalid configuration object. Webpack has been initialised using a configuration object that does not match the API schema.
 - configuration[0].module has an unknown property 'loaders'. These properties are valid:
   object { exprContextCritical?, exprContextRecursive?, exprContextRegExp?, exprContextRequest?, noParse?, rules?, defaultRules?, unknownContextCritical?, unknownContextRecursive?, unknownContextRegExp?, unknownContextRequest?, unsafeCache?, wrappedContextCritical?, wrappedContextRecursive?, wrappedContextRegExp?, strictExportPresence?, strictThisContextOnImports? }
   -> Options affecting the normal modules (`NormalModuleFactory`).

qiita.com

ググったらあった。

webpack.config.jsのloadersプロパティがunknownなので、これをrulesに変えればいいらしい。

tkfric:Sample tkfric$ webpack --watch --progress
  0% [0] compiling
webpack is watching the files…

(node:5770) DeprecationWarning: Tapable.plugin is deprecated. Use new API on `.hooks` instead
 77% [0] module and chunk tree optimization unnamed compat plugin/(Sampleディレクトリパス)/node_modules/webpack/lib/Chunk.js:824
        throw new Error(
        ^

Error: Chunk.entrypoints: Use Chunks.groupsIterable and filter by instanceof Entrypoint instead
    at Chunk.get (/(Sampleディレクトリパス)/node_modules/webpack/lib/Chunk.js:824:9)
    at /(Sampleディレクトリパス)/node_modules/extract-text-webpack-plugin/dist/index.js:176:48
    at Array.forEach (<anonymous>)
    at /(Sampleディレクトリパス)/node_modules/extract-text-webpack-plugin/dist/index.js:171:18
    at AsyncSeriesHook.eval [as callAsync] (eval at create (/(Sampleディレクトリパス)/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:12:1)
    at AsyncSeriesHook.lazyCompileHook (/Users/tkfric/WORKS/MYDEV/VuePractice/node_modules/tapable/lib/Hook.js:154:20)
    at Compilation.seal (/(Sampleディレクトリパス)/node_modules/webpack/lib/Compilation.js:1214:27)
    at hooks.make.callAsync.err (/(Sampleディレクトリパス)/node_modules/webpack/lib/Compiler.js:547:17)
    at _err0 (eval at create (/(Sampleディレクトリパス)/node_modules/tapable/lib/HookCodeFactory.js:32:10), <anonymous>:11:1)
    at _addModuleChain (/(Sampleディレクトリパス)/node_modules/webpack/lib/Compilation.js:1065:12)
    at processModuleDependencies.err (/(Sampleディレクトリパス)/node_modules/webpack/lib/Compilation.js:981:9)
    at process._tickCallback (internal/process/next_tick.js:61:11)

それでもエラーになる

ptna.hateblo.jp

$ npm i -D extract-text-webpack-plugin@next

とりあえずこのブログの通りに実行してみた

tkfric:Sample tkfric$ webpack --watch --progress
  0% [0] compiling
webpack is watching the files…

[0] Hash: a7e5ea6c26ddff43982f
Version: webpack 4.19.1
Child
    Hash: a7e5ea6c26ddff43982f
    Time: 227ms
    Built at: 2018-09-19 02:18:27
     2 assets
    Entrypoint style = style.css style.css.map
    [0] ./style.scss 1.13 KiB [built] [failed] [1 error]
    [1] ./style.scss 200 bytes [built] [failed] [1 error]
        + 2 hidden modules

    WARNING in configuration
    The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
    You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

    ERROR in ./style.scss
    Module build failed (from ../node_modules/extract-text-webpack-plugin/dist/loader.js):
    ModuleParseError: Module parse failed: Unexpected token (1:5)
    You may need an appropriate loader to handle this file type.
    > body { font-size: 14px;}
    | p { margin: 0.5em;}
    | @keyframes fade-in {
        at handleParseError (/(Sampleディレクトリパス)/node_modules/webpack/lib/NormalModule.js:432:19)
        at doBuild.err (/(Sampleディレクトリパス)/node_modules/webpack/lib/NormalModule.js:466:5)
        at runLoaders (/(Sampleディレクトリパス)/node_modules/webpack/lib/NormalModule.js:327:12)
        at /(Sampleディレクトリパス)/node_modules/loader-runner/lib/LoaderRunner.js:370:3
        at iterateNormalLoaders (/(Sampleディレクトリパス)/node_modules/loader-runner/lib/LoaderRunner.js:211:10)
        at /(Sampleディレクトリパス)/node_modules/loader-runner/lib/LoaderRunner.js:202:4
        at process.nextTick (/(Sampleディレクトリパス)/node_modules/enhanced-resolve/lib/CachedInputFileSystem.js:73:15)
        at process._tickCallback (internal/process/next_tick.js:61:11)
     @ ./style.scss

    ERROR in ./style.scss 1:5
    Module parse failed: Unexpected token (1:5)
    You may need an appropriate loader to handle this file type.
    > body { font-size: 14px;}
    | p { margin: 0.5em;}
    | @keyframes fade-in {
     @ ./style.scss 2:14-39
    Child extract-text-webpack-plugin ../node_modules/extract-text-webpack-plugin/dist ../node_modules/style-loader/index.js!style.scss:
        Entrypoint undefined = extract-text-webpack-plugin-output-filename
        [0] ../node_modules/style-loader!./style.scss 967 bytes {0} [built]
        [1] ./style.scss 200 bytes {0} [built] [failed] [1 error]
            + 2 hidden modules

        ERROR in ./style.scss 1:5
        Module parse failed: Unexpected token (1:5)
        You may need an appropriate loader to handle this file type.
        > body { font-size: 14px;}
        | p { margin: 0.5em;}
        | @keyframes fade-in {
         @ ./style.scss (../node_modules/style-loader!./style.scss) 2:14-39

まだ何か出る

WARNING in configuration
    The 'mode' option has not been set, webpack will fallback to 'production' for this value. Set 'mode' option to 'development' or 'production' to enable defaults for each environment.
    You can also set it to 'none' to disable any default behavior. Learn more: https://webpack.js.org/concepts/mode/

これはこんな記述をすれば解決するらしい。

"scripts": {
 ...
    "dev": "webpack --mode development",
    "build": "webpack --mode production",
    "production": "webpack --mode production"

でもまだ下のようなwarningが残る

    ERROR in ./style.scss
    Module build failed (from ../node_modules/extract-text-webpack-plugin/dist/loader.js):
    ModuleParseError: Module parse failed: Unexpected token (1:5)
    You may need an appropriate loader to handle this file type.

qiita.com

調べたらこの記事が出てきたのでひとまず参考に以下の記述をwebpack.config.jsに追記

    module: {
        rules: [
            ....
            { test: /\.css$/, loader: "style!css" },
            { test: /\.(png|jpg|jpeg|gif|woff)$/, loader: 'url?limit=8192' },
            { test: /\.(otf|eot|ttf)$/, loader: "file?prefix=font/" },
            { test: /\.svg$/, loader: "file" }
        ]
    },

まだエラーが残る

ERROR in Entry module not found: Error: Can't resolve 'css/style.scss' in '/(Sampleディレクトリパス)/css'

top-men.hatenablog.com

この記事を読めば最初からうまくいったのかもしれない。

いったん * cssディレクトリをsrcに変更 * context entryの記述を削除 * src下に空のindex.jsを作成 これで無事に解決した(っぽい)

tkfric:Sample tkfric$ webpack --watch --progress --mode production
  0% [0] compiling
webpack is watching the files…

[0] Hash: aa5b75cccf66cd9b1ffa
Version: webpack 4.19.1
Child
    Hash: aa5b75cccf66cd9b1ffa
    Time: 119ms
    Built at: 2018-09-19 03:18:25
           Asset      Size  Chunks             Chunk Names
        main.css  3.61 KiB       0  [emitted]  main
    main.css.map  3.51 KiB       0  [emitted]  main
    Entrypoint main = main.css main.css.map
    [0] ./src/index.js 0 bytes {0} [built]

でも結論としてはまだわかってない