Skip to content

打包多页应用

从这里开始,我们就新建一个项目,叫webpack-dev-2,来学习下面的内容。

重新建项目,并初始化项目,安装webpack相关包

新建src目录,里面新建一个index.js

js
// webpack-dev-2\src\index.js
console.log('home');

再新建一个other.js

js
// webpack-dev-2\src\other.js
console.log('other');

初始化项目,安装相关包

shell
# 初始化package.json
yarn init -y
# 安装相关包 学习多页面打包
yarn add webpack@^4.32.2 webpack-cli@^3.3.2 html-webpack-plugin@^3.2.0 -D

多页面打包

新建配置文件,我们定义两个入口,先尝试定义一个出口,打包看下效果(肯定是不行的)

js
// webpack-dev-2\webpack.config.js
let path = require('path')

module.exports = {

    // mode: 'development',

    // 入口
    // entry: '', // 以前的入口我们写的时候,直接写一个相对路径 比如 ./src/index.js
    // 现在学习多入口打包,有两个入口,所以配置一个对象,配置两个入口

    // 多入口,
    entry: {
        home: './src/index.js', // 入口1 home
        other: './src/other.js', // 入口2 other
    },
    // 因为有两个入口,所以现在也应该有两个出口
    output: {
        filename: 'bundle.js', // 以前单出口的时候这么直接写死一个就行
        // 但是多入口,对应多出口,不能直接将多入口的文件打包到一个出口文件里,这样肯定是不行的
        path: path.resolve(__dirname, 'dist')
    }
}

使用npx webpack 打包,看下效果

image-20220114105105499

红色部分报错说,有多个代码块要发射出来,但是发射到了同一个文件下,所以不行。

黄色部分警告说,是没有配置模式,默认会使用生产模式打包。

所以我们修改配置文件,多入口,就得多出口

js
// webpack-dev-2\webpack.config.js
let path = require('path')

module.exports = {

    mode: 'development',

    // 入口
    // entry: '', // 以前的入口我们写的时候,直接写一个相对路径 比如 ./src/index.js
    // 现在学习多入口打包,有两个入口,所以配置一个对象,配置两个入口

    // 多入口,
    entry: {
        home: './src/index.js', // 入口1 home
        other: './src/other.js', // 入口2 other
    },
    // 因为有两个入口,所以现在也应该有两个出口
    output: {
        // filename: 'bundle.js', // 以前单出口的时候这么直接写死一个就行
        // 但是多入口,对应多出口,不能直接将多入口的文件打包到一个出口文件里,这样肯定是不行的

        // [name] 代表home或者other
        // 相当于 home产生完打包一次,other打包完,再打包一次
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    }
}

再打包看下效果,打包成功。

image-20220114105458829

多入口打包,引入 html-webpack-plugin

先进index.html

html
<!-- webpack-dev-2\index.html -->
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
    
<body></body>
    
</html>

修改配置文件,引入html-webpack-plugin插件,因为是两个入口,所以应该生产两个入口html,先尝试一个有问题的配置,如下的配置会在两个入口文件里,把home.js和other.js都引入,我们其实不希望这样,我们希望home引home,other引other

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'development',

    // 入口
    // entry: '', // 以前的入口我们写的时候,直接写一个相对路径 比如 ./src/index.js
    // 现在学习多入口打包,有两个入口,所以配置一个对象,配置两个入口

    // 多入口,
    entry: {
        home: './src/index.js', // 入口1 home
        other: './src/other.js', // 入口2 other
    },
    // 因为有两个入口,所以现在也应该有两个出口
    output: {
        // filename: 'bundle.js', // 以前单出口的时候这么直接写死一个就行
        // 但是多入口,对应多出口,不能直接将多入口的文件打包到一个出口文件里,这样肯定是不行的

        // [name] 代表home或者other
        // 相当于 home产生完打包一次,other打包完,再打包一次
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        // 因为是两个入口,所以就应该生成两个index.html,所以new两次这个插件
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'home.html'
        }),
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'other.html'
        }),
    ],
}

打包看下结果,

image-20220114110422596

是生成了两分,但是入口文件里把home.js和other.js都引入了

image-20220114110510064

修改配置文件,home引home的,other引other的

js
// webpack-dev-2\webpack.config.js
let path = require('path')

let HtmlWebpackPlugin = require('html-webpack-plugin') // 生成html模板,将打包后的js塞进模板文件中

module.exports = {

    mode: 'development',

    // 入口
    // entry: '', // 以前的入口我们写的时候,直接写一个相对路径 比如 ./src/index.js
    // 现在学习多入口打包,有两个入口,所以配置一个对象,配置两个入口

    // 多入口,
    entry: {
        home: './src/index.js', // 入口1 home
        other: './src/other.js', // 入口2 other
    },
    // 因为有两个入口,所以现在也应该有两个出口
    output: {
        // filename: 'bundle.js', // 以前单出口的时候这么直接写死一个就行
        // 但是多入口,对应多出口,不能直接将多入口的文件打包到一个出口文件里,这样肯定是不行的

        // [name] 代表home或者other
        // 相当于 home产生完打包一次,other打包完,再打包一次
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },

    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        // 因为是两个入口,所以就应该生成两个index.html,所以new两次这个插件
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'home.html',
            chunks: ['home'], // 配置chunks,对应的入口引对应的js文件,不配置的话会全部引用
        }),
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'other.html',
            chunks: ['other'], // 配置chunks,对应的入口引对应的js文件,不配置的话会全部引用
        }),
    ],
}

再次打包看下效果,已经符合期望结果了。

image-20220114110731630

总结

多页应用打包时,需要配置多个入口,同样的,对应的入口打包后输出到对应的出口下

入口配置方式如下:

js
    // 多入口,
    entry: {
        home: './src/index.js', // 入口1 home
        other: './src/other.js', // 入口2 other
    },

出口配置如下:

js
    // 因为有两个入口,所以现在也应该有两个出口
    output: {
        // filename: 'bundle.js', // 以前单出口的时候这么直接写死一个就行
        // 但是多入口,对应多出口,不能直接将多入口的文件打包到一个出口文件里,这样肯定是不行的

        // [name] 代表home或者other
        // 相当于 home产生完打包一次,other打包完,再打包一次
        filename: '[name].js',
        path: path.resolve(__dirname, 'dist')
    },

生成html时,也需要修改一下,因为对应的入口打包后,希望塞到对应的html模板下,所以配合html-webpack-plugin使用的时候,有一个入口就new一次,多个就new多次,配置如下

js
    // 插件
    plugins: [
        // 生成html模板插件,将打包后的js以外链的形式塞到模板中
        // 因为是两个入口,所以就应该生成两个index.html,所以new两次这个插件
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'home.html',
            chunks: ['home'], // 配置chunks,对应的入口引对应的js文件,不配置的话会全部引用
        }),
        new HtmlWebpackPlugin({
            template: './index.html',
            filename: 'other.html',
            chunks: ['other'], // 配置chunks,对应的入口引对应的js文件,不配置的话会全部引用
        }),
    ],

参考

https://www.bilibili.com/video/BV1a4411e7Bz?p=12&spm_id_from=pageDriver