使用 webpack 搭建多入口项目

Posted 吃饭睡觉打豆豆

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用 webpack 搭建多入口项目相关的知识,希望对你有一定的参考价值。

闲来无事,学习一下怎么用 webpack 自定义多入口项目的打包

项目github地址:https://github.com/xiaoliwang2016/webpack-demo

先来看一下目录结构

/admin、/home:模块,可以根据需求分,也可以只需要一个模块

/htmlConfig:因为是多入口项目,因此需要一个配置文件来记录多个入口的路径,以及与模块之间的层级关系,单入口文件仅需要定义一个入口,webpack会自动追踪依赖关系,多入口需要定义多个,所以单独存起来会好一些

/webpack.config.js:webpack配置默认文件,可以根据在开发环境和生成坏境分开

/模块/html:放置页面文件

/模块/html/tpl:放置一些公用的模板

/模块/js:放置对应的js文件,名称与html页面一致

/模块/css:放置样式文件

 

然后来看一下打包后的目录

js文件统一放置在/dist/js目录,页面文件放在各自模块名称对应的目录下

看完最终效果我们来看一下webpack配置项


 

入口配置文件

首先看一下前面提到的 htmlConfig.js 文件

module.exports = {
    \'admin\' : [
        \'index\',
        \'login\'
    ],
    \'home\' : [
        \'index\'
    ]
}

很简单,就是记录了各个模块下的页面的名称,然后在webpack.config.js中拿去到这个配置项,遍历打包这些页面

 

webpack配置文件

webpack会默认读取根目录下webpack.config.js文件,通常可以将这个文件拆分成dev和pro,这里用作演示,没有分开

const path = require(\'path\')
const htmlConfig = require(\'./htmlConfig.js\')
//生成html插件
const htmlWebpackPlugin = require(\'html-webpack-plugin\')
//抽离css插件
const MiniCssExtractPlugin = require("mini-css-extract-plugin");

var htmlWebpackPlugins = []
var entrys = {}

for(var key in htmlConfig){
    htmlConfig[key].forEach(item => {
        //生成 entry 对象中的 key 例如 { admin-login: \'./admin/login.html\' }
        var k = key + \'-\' + item

        htmlWebpackPlugins.push(new htmlWebpackPlugin({
            //template设置根据那个模板生成
            template: `./src/${key}/html/${item}.html`,
            //生成html名称
            filename: `./${key}/${item}.html`,
            //chunks 设置需要引入的JS模块
            chunks: [k],
            //自动引入js 可选:true(底部)/body/head
            inject: true,
        }))

        entrys[k] = `./src/${key}/js/${item}.js`
    })
}

module.exports = {
    mode: \'production\',
    entry: entrys,
    output: {
        path: path.resolve(__dirname, \'dist\'),
        // name:对应entry的key ,chunkhash根据文件进行MD5自动计算
        filename: \'js/[name]-[chunkhash].js\',
        //上线时可以使用 publicPath替换根路径 
        // publicPath: \'http://cdn.com/\'
    },
    module:{
        rules: [
            { 
                test: /\\.js$/, 
                //排除项
                exclude: path.resolve(__dirname, \'node_modules\'),
                //选择项
                include: path.resolve(__dirname, \'src\'),
                loader: "babel-loader",
                //babel需要配合 babel-preset-env 一起使用
                query: {
                    "presets": ["env"]
                }
            },
            {
                test: /\\.css$/,
                //同一个文件需要多个loader的情况下可以使用数组,执行顺序根据数组从后往前执行
                use: [
                    //使用MiniCssExtractPlugin.loader代替style-loader抽离css成单独文件
                    MiniCssExtractPlugin.loader,
                    // \'style-loader\',
                    //每个loader可以有自己的参数,options字段就是定义参数
                    { loader: \'css-loader\', options: {importLoaders: 1}},
                    {
                      loader: \'postcss-loader\',
                      options: {
                        ident: \'postcss\',
                        //autoprefixer是postcss-loader的一个插件,需要安装,用于给css添加前缀
                        plugins: [
                          require(\'autoprefixer\')({
                              cascade: false
                          })
                        ]
                      }
                    }
                ]
            },
            {
                test: /\\.tpl$/,
                loader: \'ejs-loader\'
            }
        ]
    },
    plugins: [
        new MiniCssExtractPlugin({
          filename: "css/[name].css",
          chunkFilename: "[id].css"
        }),
        ...htmlWebpackPlugins
    ]
}

注意:这里需要注意的是使用 loader 打包文件时调用 loader 的顺序时根据数组从后往前,因此这里处理css文件的顺序时:

postcss-loader --> css-loader --> style-loader

* postcss-loader是一个css后处理器,他提供很多插件可以处理css文件,例如css自动添加前缀,压缩等等

loader

js

webpack默认只会处理js文件,因此如果有需要处理不同文件时需要指定对应的loader

例如常用转换js语法的loader:babel-loader

安装:

npm install babel-loader --save-dev
npm install babel-preset-env --save-dev

然后需要在制定位置添加 presets 配置项

可以是 padkjson.js 或者 .babelrc 文件 或者webpack.config.js中

 

模板

多入口文件一般一个页面对应一个js文件,可以在js文件中再次引入其他的模板(页面),在通过loader解析最后插入到当前页面

 

例如这里的/admin/js/index.js对应的模板时/admin/html/index.html,然而还可以在index.js中引入一些其他的模板,例如引入admin/html/tpl/table.tpl,然后渲染插入到index.html中

在处理模板文件时可以根据不同的模板设置不同的loader处理,这里演示的是ejs的模板

<table class="table">
    <tr>
        <th>brand</th>
        <th>name</th>
        <th>price</th>
    </tr>
    <% for(var i = 0; i < data.length; i++) { %>
        <tr>
            <td><%= data[i].brand %></td>
            <td><%= data[i].name %></td>
            <td><%= data[i].price %></td>
        </tr>
    <% } %>
</table>

在webpack.config.js中配置loader

{
    test: /\\.tpl$/,
    loader: \'ejs-loader\'
}

在js文件中可以直接通过import的放置引入该模板文件

import table from \'../html/layer/table.tpl\'

ejs-loader处理完成后会返回一个函数(html-loader返回为字符串),函数的参数为模板的变量,例如在admin/js/index.js文件中引入模板然后插入到页面

import \'../css/index.css\'
import table from \'../html/layer/table.tpl\'

document.querySelector(\'#table\').innerHTML = table({
    data : [
        {brand: \'MI\', name: \'MI6\', price: 2999},
        {brand: \'iphone\', name: \'iphoneX\', price: 9999}
    ]
})

生成后页面

 

样式

 可以在js中直接通过import的方式引入

import \'../css/index.css\'

也可以在css中引入其他的css文件

@import \'./common.css\';

css文件中分号一定要带上

 

以上是关于使用 webpack 搭建多入口项目的主要内容,如果未能解决你的问题,请参考以下文章

搭建 vue2 vue-router2 webpack3 多入口工程

# Webpack 学习Webpack 搭建 Vue项目

# Webpack 学习Webpack 搭建 Vue项目

一文搞懂 Webpack 多入口配置

webpack解惑:多入口文件打包策略

React多页面应用4(webpack自动化生成多入口页面)