美文网首页
webpack4 - 8.整合jquery等第三方库

webpack4 - 8.整合jquery等第三方库

作者: yuanzicheng | 来源:发表于2018-09-24 17:48 被阅读655次

    虽然目前angular/react/vue这些现代化的框架使前端开发模式发生了极大的变化,但是有些东西还是需要依靠我们的老朋友jquery来实现。

    1.引入jquery

    我们继续使用之前的代码,引入jquery。

    1.1 使用import手动引入jquery

    安装jquery依赖

    npm install jquery
    

    src/js/index/js中引入jquery,使用jquery来修改页面的title内容

    import '../css/index.css'
    import Vue from 'vue'
    import test from '../vue/test.vue'
    import $ from 'jquery'
    new Vue({
        el: '#test',
        render: h => h(test)
    });
    
    $("title").html('title by jquery');
    

    src/vue/test.vue中引入jquery,使用jquery来动态修改div中的内容

    <template>
        <div id="demo">
            <h1>Hello,{{msg}}</h1>
            <input type="text" v-model="msg">
            <div id="jquery"></div>
        </div>
    </template>
    <script>
        import $ from 'jquery'
        export default {
            data () {
                return {
                    msg: 'xxx12314`'
                }
            },
            mounted () {
                $("#jquery").html("Hello jQuery!");
            }
        }
    </script>
    <style scoped>
        #demo {
            background: yellow;
        }
    </style>
    

    到这里为止引入jquery的工作就完成了,使用webpack-dev-server打开页面进行测试,看到预期的结果,证明jquery引入成功,能够正常使用。

    另外,使用webpack命令进行打包,可以发现在生成的.js文件中,jquery的内容也被包含在内了。

    1.2 使用ProvidePlugin自动引入jquery

    从上面的例子可以发现,分别在src/js/index.jssrc/vue/test.vue中使用了import来引入jquery,这种方式必须在每个需要引入jquery的文件中写上一句import $ from 'jquery'

    ProvidePlugin这个插件可以自动加载模块,无需每处 importrequire 。接下来就用这个插件来试验。

    webpack.config.js中添加ProvidePlugin相关配置

    const path = require('path');
    const webpack = require('webpack');
    const MiniCssExtractPlugin = require('mini-css-extract-plugin');
    const HtmlWebpackPlugin = require('html-webpack-plugin');
    const VueLoaderPlugin = require('vue-loader/lib/plugin');
    
    module.exports = {
        mode: 'production',
        entry: {
            index: './src/js/index.js'
        },
        output: {
            path: path.resolve(__dirname, 'dist'),
            filename: 'js/[name].[hash:8].js'
        },
        module: {
            rules: [
                {
                    test: /\.vue$/,
                    use: 'vue-loader'
                },
                {
                    test: /\.js$/,
                    use: 'babel-loader',
                    exclude: /node_modules/
                },
                {
                    test: /\.css$/,
                    use: [
                        {
                            loader: MiniCssExtractPlugin.loader,
                            options: {
                                publicPath: '../'  // 特别重要,否则css文件打包后其中引用的图片文件不正确
                            }
                        },
                        "css-loader"
                    ]
                },
                {
                    test: /\.html$/,
                    use: {
                        loader: 'html-loader'
                    }
                },
                {
                    test: /\.(png|jpg|gif|jpeg|svg)$/,
                    use:[
                        {
                            loader: "url-loader",
                            options: {
                                name: "img/[name].[hash:5].[ext]",
                                limit: 1024, // size <= 1kib
                                // outputPath: "img",
                                publicPath: "../"
                            }
                        }
                    ]
                }
            ]
        },
        plugins: [
            new MiniCssExtractPlugin({
                filename: "css/[name].[hash:8].css",
            }),
            new HtmlWebpackPlugin(
                {
                    template: './src/page/index.html',
                    filename:'./page/index.html',
                    hash: false,
                    chunks: ['index']
                }
            ),
            new VueLoaderPlugin(),
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery'
            })
        ],
        devServer: {
            contentBase: path.resolve(__dirname, "../dist/"),
            index:'./page/index.html'
        }
    };
    

    去除src/js/index.jssrc/vue/test.vue中的import $ from 'j query'

    使用webpck-dev-server打开页面后jquery相关的效果依然存在,并且检查页面资源,发现原来的js文件中依然有jquery相关代码,说明使用ProvidePlugin能够实现模块自动加载。

    前面的文章中使用了import Vue from 'vue'来引入vue.js,有了ProvidePlugin之后,vue.js也可以用它来动态引入

    new webpack.ProvidePlugin({
      Vue: ['vue/dist/vue.esm.js', 'default']
    });
    

    2.引入jquery插件

    这里以iziToastiziModal这两个基于jquery的弹出框插件为例。

    iziToast.png iziModal.png

    顺便吐槽一下,市面上一些的UI组件中的对话框真的丑,而且功能少,还有bug!(iView中的Modal全屏模式在中小尺寸的屏幕上显示错乱的问题到了3.x版本一直都没解决,之前的项目中用到了这个,能力有限自己解决不了bug,无奈只能改设计方案,放弃了全屏窗口的功能。)


    iView-Modal.png

    废话不多说了,基于前文的项目代码,开始引入插件。

    安装插件

    npm install --save izitoast izimodal
    

    webpack.config.js中配置自动加载插件

    module.exports = {
        mode: 'development',
        entry: {
            index: './src/js/index.js'
        },
        output: {
            ...
        },
        module: {
            ...
        },
        plugins: [
            ...
            new webpack.ProvidePlugin({
                $: 'jquery',
                jQuery: 'jquery',
                Vue: ['vue/dist/vue.esm.js', 'default'],
                iziToast: 'izitoast',
                iziModal: 'izimodal'
            })
        ],
        devServer: {
            ...
        }
    };
    

    这里我们在vue组件中使用这两个插件,新增一个.vue文件
    src/vue/izi.vue(点击两个链接,分别弹出iziToast和iziModal)

    <template>
        <div>
            <a href="#" @click="toast">iziToast</a>
            <a href="#" class="trigger">iziModal</a>
            <div id="modal">
                <p>1</p>
                <p>2</p>
            </div>
        </div>
    </template>
    <script>
        export default {
            data () {
                return {}
            },
            mounted () {
                $.fn.iziModal = iziModal;
                $("#modal").iziModal({
                    title: 'AAAAAAAA',
                    subtitle: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
                    headerColor: 'yellowgreen',
                    fullscreen: true
                });
                $(document).on('click', '.trigger', function (event) {
                    event.preventDefault();
                    $('#modal').iziModal('open');
                });
            },
            methods: {
                toast () {
                    iziToast.show({
                        title: 'Hey',
                        message: 'What would you like to add?'
                    });
                }
            }
        }
    </script>
    <style scoped>
    </style>
    

    index.htmlindex.js稍作修改,去除无关的代码
    src/page/index.html

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="UTF-8">
        <title>Title</title>
    </head>
    <body>
    <div id="app">
        <izi></izi>
    </div>
    </body>
    </html>
    

    src/js/index.js(引入插件相关的css及自己定义的vue组件)

    import 'izitoast/dist/css/iziToast.min.css'
    import 'izimodal/css/iziModal.min.css'
    import izi from '../vue/izi.vue'
    new Vue({
        el: '#app',
        components: {izi}
    });
    

    使用webpack-dev-server打开页面后,点击两个链接,iziToast和iziModal均能正常显示,插件初步引入成功。

    izi.png

    但是,别高兴得太早!我们在<div id="modal"></div>中加入一些vue.js的代码

    <template>
        <div>
            <a href="#" @click="toast">iziToast</a>
            <a href="#" class="trigger">iziModal</a>
            <div id="modal">
                <h1>Hello,{{ msg }}</h1>
                <input name="msg" type="text" v-model="msg">
            </div>
        </div>
    </template>
    

    <script>中的data加入一项msg

    <script>
        export default {
            data () {
                return {
                    msg: 'xxxx'
                }
            },
            mounted () {
                ...
            },
            methods: {
                ...
            }
        }
    </script>
    

    重新打开弹出框,在其中的输入框填入任意的内容,What?<h1>标签中的msg内容居然没有一起改变,说明经过iziModal初始化后的vue.js相关功能已经失效了!这个问题在github已经存在issue#115afterRender这个选项能够提供一些补救措施,但是依然不能在iziModal中直接使用vue.js。本人能力有限,暂时不在这里白费力气了,目前只能退而求其次不在iziModal中使用vue.js了,或者不使用iziModal。

    $("#modal").iziModal({
        title: 'AAAAAAAA',
        subtitle: 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb',
        headerColor: 'lightcoral',
        fullscreen: true,
        afterRender: function() {
            $('input[name="msg"]').on('change', function () {
            });
        }
    });
    

    相关文章

      网友评论

          本文标题:webpack4 - 8.整合jquery等第三方库

          本文链接:https://www.haomeiwen.com/subject/rfaanftx.html