• 使用 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文件中分号一定要带上

  • 相关阅读:
    线段树lazy标记??Hdu4902
    3D游戏引擎〇 開始
    实时分析之客户画像项目实践
    ubuntu14.04系统中virtualbox安装Oracle VM VirtualBox Extension Pack包
    《Android源代码设计模式解析与实战》读书笔记(二十二)
    最长递增子序列的数量
    springmvc学习笔记(19)-RESTful支持
    hadoop(三):hdfs 机架感知
    hadoop(二):hdfs HA原理及安装
    hadoop(一):深度剖析hdfs原理
  • 原文地址:https://www.cnblogs.com/xiaoliwang/p/10203167.html
Copyright © 2020-2023  润新知