webpack指令npm start出现错误Cannot use [chunkhash] for chunk

项目在webpack01文件内-->地址

{
  "name": "webpack01",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1",
    "watch": "webpack --watch --config webpack.dev.js",
    "start": "webpack-dev-server --inline --hotOnly --config webpack.dev.js",
    "build": "webpack --config webpack.prod.js"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "devDependencies": {
    "babel-core": "^6.26.0",
    "babel-loader": "^7.1.2",
    "babel-plugin-transform-runtime": "^6.23.0",
    "babel-preset-env": "^1.6.0",
    "babel-preset-es2015": "^6.24.1",
    "babel-preset-react": "^6.24.1",
    "babel-preset-stage-0": "^6.24.1",
    "clean-webpack-plugin": "^0.1.17",
    "css-loader": "^0.28.7",
    "express": "^4.16.1",
    "html-webpack-plugin": "^2.30.1",
    "style-loader": "^0.18.2",
    "uglifyjs-webpack-plugin": "^0.4.6",
    "webpack": "^3.6.0",
    "webpack-dev-middleware": "^1.12.0",
    "webpack-dev-server": "^2.9.1",
    "webpack-merge": "^4.1.0"
  },
  "dependencies": {
    "lodash": "^4.17.4"
  }
}

webpack.common.js

const path = require('path');
// HtmlWebpackPlugin 还是会默认生成 index.html 文件。
// 这就是说,它会用新生成的 index.html 文件,把我们的原来的替换。
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 通常,在每次构建前清理 /dist 文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。
// clean-webpack-plugin 是一个比较普及的管理插件,让我们安装和配置下
const CleanWebpackPlugin = require('clean-webpack-plugin');

const webpack = require('webpack');// 热加载需要的 webpack

module.exports = {
    /*
    entry: {
        // app: './src/index.js',
        // print: './src/print.js'
        // app: './src/index.js'
        index: './src/index.js',
        another: './src/another-module.js'
    },
    */
    /*
        将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,是比较推荐的做法,
        这是因为,它们很少像本地的源代码那样频繁修改。

        因此通过实现以上步骤,利用客户端的长效缓存机制,可以通过命中缓存来消除请求,并减少向服务器获取资源,
        同时还能保证客户端代码和服务器端代码版本一致。这可以通过使用新的 entry(入口) 起点,
        以及再额外配置一个 CommonsChunkPlugin 实例的组合方式来实现
     */

    entry: {
        index: './src/index.js',
        another: './src/another-module.js',
        vendor: [
            'lodash'
        ]
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            }
        ]
    },
    plugins: [
        // 每次都会清理 dist 文件夹的内容
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            // title: 'Production'
            title: 'Caching'
        }),
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common' // 指定公共 bundle 的名称。
        }),
        new webpack.HotModuleReplacementPlugin(), // 热加载的插件
        /*
        以下是由社区提供的,一些对于代码分离很有帮助的插件和 loaders:

            ExtractTextPlugin: 用于将 CSS 从主应用程序中分离。
            bundle-loader: 用于分离代码和延迟加载生成的 bundle。
            promise-loader: 类似于 bundle-loader ,但是使用的是 promises。

        CommonsChunkPlugin 插件还可以通过使用显式的 vendor chunks 功能,从应用程序代码中分离 vendor 模块
        */
        /*
            幸运的是,可以使用两个插件来解决这个问题。
            第一个插件是 NamedModulesPlugin,将使用模块的路径,而不是数字标识符。
            虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。

            第二个选择是使用 HashedModuleIdsPlugin,推荐用于生产环境构建
         */
        new webpack.HashedModuleIdsPlugin(),
        /*
            然而 CommonsChunkPlugin 有一个较少有人知道的功能是,能够在每次修改后的构建结果中,
            将 webpack 的样板(boilerplate)和 manifest 提取出来。通过指定 entry 配置中未用到的名称,
            此插件会自动将我们需要的内容提取到单独的包中
         */
        new webpack.optimize.CommonsChunkPlugin({
            name: 'runtime'
        }),
        /*
            将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,
            是比较推荐的做法,这是因为,它们很少像本地的源代码那样频繁修改。
            因此通过实现以上步骤,利用客户端的长效缓存机制,可以通过命中缓存来消除请求,
            并减少向服务器获取资源,同时还能保证客户端代码和服务器端代码版本一致。
            这可以通过使用新的 entry(入口)起点,以及再额外配置一个 CommonsChunkPlugin 实例的组合方式来实现
         */
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor'
        }),
    ],
    // 修改配置文件,告诉开发服务器(dev server)在哪里查找文件
    output: {
        //filename: '[name].bundle.js',
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    }
};

webpack.dev.js

const merge = require('webpack-merge');
const common = require('./webpack.common.js');
/*
    开发环境(development)和生产环境(production)的构建目标差异很大。
    在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)
    或热模块替换(hot module replacement)能力的 source map 和 localhost server。

    而在生产环境中,我们的目标则转向于关注更小的 bundle,更轻量的 source map,
    以及更优化的资源,以改善加载时间。

    由于要遵循逻辑分离,我们通常建议为每个环境编写彼此独立的 webpack 配置。

    虽然,以上我们将生产环境和开发环境做了略微区分,
    但是,请注意,我们还是会遵循不重复原则(Don't repeat yourself - DRY),
    保留一个“通用”配置。

    为了将这些配置合并在一起,我们将使用一个名为 webpack-merge 的工具。
    通过"通用"配置,我们不必在环境特定(environment-specific)的配置中重复代码。

    我们先从安装 webpack-merge 开始,并将之前指南中已经成型的那些代码再次进行分离

    npm install --save-dev webpack-merge
 */

/*

    在开发环境中,我们需要具有强大的、具有实时重新加载(live reloading)
    或热模块替换( hot module replacement )能力的 source map 和 localhost server

 */
module.exports = merge(common, {
    devtool: 'inline-source-map',
    // 修改配置文件,告诉开发服务器(dev server)在哪里查找文件
    devServer: {
        contentBase: './dist',
        hot: true // 服务器热加载
    }
});

图片描述

阅读 7k
2 个回答

热更新(HMR)不能和[chunkhash]同时使用。

output: {
       //filename: '[name].bundle.js',
       filename: '[name].[chunkhash].js',
       path: path.resolve(__dirname, 'dist')
   }

解决方法:
1: 如果是开发环境,将配置文件中的chunkhash 替换为hash
2:如果是生产环境,不要使用参数 --hot

运行webpack,如果报了下面这个错误

ERROR in chunk runtime [entry]
[name].[chunkhash].js
Cannot use [chunkhash] for chunk in '[name].[chunkhash].js' (use [hash] instead)

那你就把plugins里面的热替换插件注释掉就好了,上线的config不需要热替换:

plugins: [
    //new hotModuleReplacementPlugin(),
]

webpack.common.js

const path = require('path');
// HtmlWebpackPlugin 还是会默认生成 index.html 文件。
// 这就是说,它会用新生成的 index.html 文件,把我们的原来的替换。
const HtmlWebpackPlugin = require('html-webpack-plugin');
// 通常,在每次构建前清理 /dist 文件夹,是比较推荐的做法,因此只会生成用到的文件。让我们完成这个需求。
// clean-webpack-plugin 是一个比较普及的管理插件,让我们安装和配置下
const CleanWebpackPlugin = require('clean-webpack-plugin');

const webpack = require('webpack');// 热加载需要的 webpack



module.exports = {
    /*
    entry: {
        // app: './src/index.js',
        // print: './src/print.js'
        // app: './src/index.js'
        index: './src/index.js',
        another: './src/another-module.js'
    },
    */
    /*
        将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,是比较推荐的做法,
        这是因为,它们很少像本地的源代码那样频繁修改。

        因此通过实现以上步骤,利用客户端的长效缓存机制,可以通过命中缓存来消除请求,并减少向服务器获取资源,
        同时还能保证客户端代码和服务器端代码版本一致。这可以通过使用新的 entry(入口) 起点,
        以及再额外配置一个 CommonsChunkPlugin 实例的组合方式来实现
     */

    entry: {
        index: './src/index.js',
        another: './src/another-module.js',
        vendor: [
            'lodash'
        ]
    },
    module: {
        rules: [
            {
                test: /\.css$/,
                use: ['style-loader', 'css-loader']
            },
            {
                test: /\.js$/,
                // include 表示哪些目录中的 .js 文件需要进行 babel-loader
                // exclude 表示哪些目录中的 .js 文件不要进行 babel-loader
                exclude: /(node_modules|bower_components)/,
                use: {
                    loader: 'babel-loader',
                    options: {
                        presets: ['env', 'react', 'stage-0']
                    }
                }
            },
            {
                test:/\.jsx?$/,
                exclude:/node_modules/,
                loader:'babel-loader',
                query:{
                    // presets:['es2015','react']
                    presets:['env', 'react', 'stage-0']
                }
            }
        ]
    },
    plugins: [
        // 每次都会清理 dist 文件夹的内容
        new CleanWebpackPlugin(['dist']),
        new HtmlWebpackPlugin({
            // title: 'Production'
            title: 'Caching'
        }),
        /*
        new webpack.optimize.CommonsChunkPlugin({
            name: 'common' // 指定公共 bundle 的名称。
        }),
        */
        // new webpack.HotModuleReplacementPlugin(), // 热加载的插件
        /*
        以下是由社区提供的,一些对于代码分离很有帮助的插件和 loaders:

            ExtractTextPlugin: 用于将 CSS 从主应用程序中分离。
            bundle-loader: 用于分离代码和延迟加载生成的 bundle。
            promise-loader: 类似于 bundle-loader ,但是使用的是 promises。

        CommonsChunkPlugin 插件还可以通过使用显式的 vendor chunks 功能,从应用程序代码中分离 vendor 模块
        */
        /*
            幸运的是,可以使用两个插件来解决这个问题。
            第一个插件是 NamedModulesPlugin,将使用模块的路径,而不是数字标识符。
            虽然此插件有助于在开发过程中输出结果的可读性,然而执行时间会长一些。

            第二个选择是使用 HashedModuleIdsPlugin,推荐用于生产环境构建
         */
        new webpack.HashedModuleIdsPlugin(),
        /*
            将第三方库(library)(例如 lodash 或 react)提取到单独的 vendor chunk 文件中,
            是比较推荐的做法,这是因为,它们很少像本地的源代码那样频繁修改。
            因此通过实现以上步骤,利用客户端的长效缓存机制,可以通过命中缓存来消除请求,
            并减少向服务器获取资源,同时还能保证客户端代码和服务器端代码版本一致。
            这可以通过使用新的 entry(入口)起点,以及再额外配置一个 CommonsChunkPlugin 实例的组合方式来实现
        */
        new webpack.optimize.CommonsChunkPlugin({
            name: 'vendor'
        }),
        /*
            然而 CommonsChunkPlugin 有一个较少有人知道的功能是,能够在每次修改后的构建结果中,
            将 webpack 的样板(boilerplate)和 manifest 提取出来。通过指定 entry 配置中未用到的名称,
            此插件会自动将我们需要的内容提取到单独的包中
         */
        new webpack.optimize.CommonsChunkPlugin({
            name: 'runtime'
        })
    ],
    // 修改配置文件,告诉开发服务器(dev server)在哪里查找文件
    output: {
        // filename: '[name].bundle.js',
        filename: '[name].[chunkhash].js',
        path: path.resolve(__dirname, 'dist')
    }
};


图片描述

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏