【问题标题】:Import bootstrap js more than once doesn't work typescript多次导入引导 js 不起作用打字稿
【发布时间】:2019-02-21 17:06:39
【问题描述】:

我正在使用带有 symfony Webpack encore 插件的 Symfony 4.1 和 Typescript 3.0.3 的网络应用程序。

问题是当我在 ./assets/js/app.ts 中导入引导程序时:

import 'bootstrap';

jQuery(function () {
    $('#clock-timetable').popover();
    $('#form_popover').popover();
});

然后在另一个文件中再次导入 ./assets/js/home/example.ts

import 'bootstrap';
import 'bootstrap-select';

export class Example {
    readonly element: JQuery;

    constructor(element: JQuery) {
        this.element = element;
    }

    render(data: Array<SelectorData>): void {
        for (let obj of data) {
            this.element.append("<option data-icon='fa fa-map-marker' value='" + obj.code + "'>" + obj.name + "</option>");
        }

        this.element.selectpicker('refresh');
    }
}

选择器不起作用。但是,如果我在我的 app.ts 脚本中更改 bootstrap 的导入并仅导入 'bootstrap/js/dist/popover' 它可以工作。请注意,无论 TS 编译器,JS 控制台都不会抛出任何警告。

我的webpack.config.js

var Encore = require('@symfony/webpack-encore');

Encore
    .setOutputPath('public/build/')
    .setPublicPath('/build')
    .cleanupOutputBeforeBuild()
    .enableBuildNotifications()
    .autoProvidejQuery()
    .enableSourceMaps(!Encore.isProduction())
    .enableVersioning(Encore.isProduction())
    .addEntry('js/app', './assets/js/app.ts')
    .addEntry('js/home/example', './assets/js/home/example.ts')
    .enableTypeScriptLoader()
;

module.exports = Encore.getWebpackConfig();

我的tsconfig.json

{
  "compilerOptions": {
    "module": "commonjs",
    "target": "es5",
    "sourceMap": true
  },
  "exclude": [
    "node_modules"
  ],
  "include": [
    "./assets/js/**/*"
  ]
}

我的package.json

{
    "devDependencies": {
        "@symfony/webpack-encore": "^0.20.0",
        "webpack-notifier": "^1.6.0"
    },
    "license": "UNLICENSED",
    "private": true,
    "scripts": {
        "dev-server": "encore dev-server",
        "dev": "encore dev",
        "watch": "encore dev --watch",
        "build": "encore production"
    },
    "dependencies": {
        "@types/bootstrap": "^4.1.2",
        "@types/bootstrap-select": "^1.11.1",
        "@types/jquery": "^3.3.6",
        "@types/jqueryui": "^1.12.4",
        "bootstrap": "^4.1.3",
        "bootstrap-select": "^1.13.2",
        "font-awesome": "^4.7.0",
        "jquery": "^3.3.1",
        "jquery-ui": "^1.12.1",
        "popper.js": "^1.14.4",
        "ts-loader": "^3.5.0",
        "typeface-montserrat": "^0.0.54",
        "typescript": "^3.0.3"
    }
}

base.html.twig:

    <!DOCTYPE html>
    <html>
        <head>
            <meta charset="UTF-8">
            <meta name="viewport" content="width=device-width, initial-scale=1">
            <link rel="shortcut icon" href="{{ asset('images/favicon.ico') }}"/>

            <title>{% block title %} {{ 'company.name' | trans }} {% endblock %}</title>

            {% block stylesheets %}
                <link rel="stylesheet" type="text/css" href="{{ asset('build/css/app.css') }}">
            {% endblock %}
        </head>
        <body>
        {{ render(controller('App\\Controller\\CommonController::navBar')) }}

        {% block body %}{% endblock %}

        {{ render(controller('App\\Controller\\CommonController::footer')) }}

        {% block javascripts %}
            <script type="text/javascript" language="javascript" src="{{ asset('build/js/app.js') }}"></script>
        {% endblock %}
        </body>
    </html>

我的index.html.twig

{% extends 'base.html.twig' %}

{% block body %}

    <div class="container">
        {{ render(controller('App\\Controller\\HomeController::example')) }}

    </div>

{% endblock %}

{% block javascripts %}
    {{ parent() }}
    <script type="text/javascript" language="javascript" src="{{ asset('build/js/home/example.js') }}"></script>
{% endblock %}

问题:为什么我不能在不同的文件中导入两次引导程序?

编辑:这里是问题的一个例子:https://github.com/soasada/example-project

【问题讨论】:

  • 根据代码我不知道答案,但如果你发布一个存储库,我会玩它。
  • 您好,马特,这里有一个完整的问题示例:github.com/soasada/example-project,我为您提供了一个 vagrantfile 来使用该示例。如果您在 app.ts 脚本中删除 import 'bootstrap',则 home.ts 中的选择器代码可以完美运行。我哪里错了?我想我忘记了什么。

标签: jquery typescript symfony webpack


【解决方案1】:

好的,根据 Matt McCutchen 的回答,我已经能够修复这个错误,我需要的是一个与项目的主要依赖项共享的条目。这可以通过 Symfony webpack encore 的 .createSharedEntry(name: string, files: Array[string]) 方法实现。

您需要 jquery、jquery-ui、bootstrap 和 bootstrap-select javascript 依赖项的图像,此行与所有打包的依赖项组成一个共享条目:

.createSharedEntry('js/common', ['jquery', 'bootstrap', 'bootstrap-select', 'jquery-ui'])

https://github.com/soasada/example-project有一个解决方案的例子。

【讨论】:

    【解决方案2】:

    您正在制作和加载两个单独的 Webpack 包,每个包都包含一个 Bootstrap 副本,每个副本都将单击事件处理程序与具有 data-toggle="dropdown" 属性的元素相关联。 bootstrap-select 在它创建的菜单上设置这个属性。因此,当您单击菜单时,两个事件处理程序都会运行并尝试处理该事件。显然这不可能奏效。

    解决此问题的一种方法是将所有代码放在一个 Webpack 包中。我想还有其他可能的方法,但我不熟悉该领域的最佳实践。

    【讨论】:

      猜你喜欢
      • 2016-11-21
      • 2016-07-13
      • 1970-01-01
      • 2023-03-21
      • 1970-01-01
      • 2019-08-29
      • 2017-05-07
      • 1970-01-01
      • 2020-04-19
      相关资源
      最近更新 更多