webpack5开发环境配置

41 阅读2分钟

通过express、webpack-dev-middleware、webpack-hot-middleware(通过EventSource实现HMR)

webpack.dev.js
const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');

// 基础配置
const baseConfig = require('./webpack.base.js')

// devServeConfig 配置
const DEV_SERVE_CONFIG = {
    HOST: '127.0.0.1',
    PORT: 9002,
    MAR_PATH: '__webpack_hmr',
    TIMEOUT: 20000
}

// 开发阶段的 entry 配置需要加入 hmr
Object.keys(baseConfig.entry).forEach(v => {
    // 第三方包不作为 hmr 入口
    if (v !== 'vendor') {
        baseConfig.entry[v] = [
            // 主文件入口
            baseConfig.entry[v],
            // hmr 更新入口,官方指定路径
            `webpack-hot-middleware/client?path=http://${DEV_SERVE_CONFIG.HOST}:${DEV_SERVE_CONFIG.PORT}/${DEV_SERVE_CONFIG.MAR_PATH}&timeout=${DEV_SERVE_CONFIG.TIMEOUT}&reload=true`
        ]
    }
})

const webpackConfig = merge(baseConfig, {
    // 开发环境
    mode: 'development',
    // source-map 开发工具,页面打开调试工具方便调试
    devtool: 'inline-source-map',
    // devtool: 'eval-cheap-module-source-map',
    
    output: {
        filename: 'js/[name]_[chunkhash:8].bundle.js',
        path: path.resolve(process.cwd(), './app/public/dist/dev/'), // 输出文件存储路径
        publicPath: `http://${DEV_SERVE_CONFIG.HOST}:${DEV_SERVE_CONFIG.PORT}/public/dist/dev/`, // 静态资源引用路径
        globalObject: 'this'// 支持多环境打包
    },
    plugins: [
        // HotModuleReplacementPlugin 用于实现热模块替换,HMR
        // 模块热替换运行在应用程序时替换
        // 极大的提升开发效率,因为能让应用程序一直保持运行状态
        new webpack.HotModuleReplacementPlugin({
            multiStep: false
        })
    ]
})

module.exports = {
    // webpack配置
    webpackConfig,
    // devServe 配置,暴露给 dev.js 使用
    DEV_SERVE_CONFIG
}


dev.js
const express = require('express');
const path = require('path');
const consoler = require('consoler');
const webpack = require('webpack');

// EventSource

//  作用是以监听模式启动 webpack,将编译后的文件输出到内存,为服务器提供资源服务
const devMiddleware = require('webpack-dev-middleware');

// 实现热模块替换(HMR),进一步优化开发体验‌
const hotMiddleware = require('webpack-hot-middleware');

// 从webpack.dev.js 获取 webpack 配置 和 devServe 配置
const {
    // webpack配置
    webpackConfig,
    // devServe 配置
    DEV_SERVE_CONFIG
} = require('./config/webpack.dev.js');

const app = express();

const complier = webpack(webpackConfig);

// 指定静态文件目录
app.use(express.static(path.join(__dirname, '../public/dist')));

// 引用devMiddleware 中间件(监控文件改动)
app.use(devMiddleware(complier, {
    // 落地文件,过滤掉tpl文件,不需要落地到内存中
    writeToDisk: (filePath) => filePath.endsWith('.tpl'),

    // 资源路径
    publicPath: webpackConfig.output.publicPath,

    // headers 配置
    headers: {
        'Access-Control-Allow-Origin': '*',
        'Access-Control-Allow-Methods': 'GET,POST,DELETE,PUT,OPTIONS,OPTIONS',
        'Access-Control-Allow-Headers': 'X-Requested-With, Content-Type, Authorization',
    },
    stats: {
        colors: true
    }
}))

// 引用 hotMiddleware 中间件(实现热更新通讯)
app.use(hotMiddleware(complier, {
    path: `/${DEV_SERVE_CONFIG.MAR_PATH}`,
    log: () => {
        consoler.info('热更新成功')
    }
}))

consoler.info('请等待webpack初次构建完成提示....')

// 获取端口
const port = DEV_SERVE_CONFIG.PORT;

// 启动 dev 服务
app.listen(port, () => {
    console.log(`webpack dev server is running at http://localhost:${port}`);
});