javascript - Pourquoi le chargement à la demande de Webpack2 ne prend-il pas effet?
世界只因有你
世界只因有你 2017-05-19 10:26:20
0
4
769

Je viens de commencer à entrer en contact avec le développement modulaire front-end. J'ai écrit une démo pour apprendre le webpack. Je comprends essentiellement le fichier de configuration et le processus de fonctionnement, mais le chargement à la demande échoue toujours :

.

Dans le fichier d'entrée, 3 méthodes sont utilisées pour charger :

import test from './index/test.js';  
            
// const test=(resolve) => require(['./index/test.js'], resolve)
        
// const test=resolve => { require.ensure(['./index/test.js'], () => { resolve(require('./index/test.js')) }) }
    
test.exe('显示测试文字');//执行

Le contenu de test.js est très simple, il suffit d'imprimer sur la console :

const test={
    exe:function (res) {
        console.log('test方法的输出:'+res);
    }
};
export default test

Trois méthodes ont été testées. Seule la première méthode d'importation directe s'exécute normalement. Les deux autres méthodes de chargement à la demande signaleront une erreur, indiquant que la méthode est introuvable.
Si vous commentez test.exe('显示测试文字'); et que vous chargez uniquement mais pas exécutez, aucune erreur ne sera signalée.
Je crois comprendre qu'il n'y a rien de mal à charger les codes, mais lorsqu'ils doivent être chargés, ils ne le sont pas correctement. Pourquoi ? Ai-je écrit quelque chose de mal quelque part ? Ou dois-je effectuer une configuration supplémentaire sur webpack.config.jx ?

世界只因有你
世界只因有你

répondre à tous(4)
淡淡烟草味

Donnez-vous un exemple pour référence

html

<input class="btn" type="button" name="" value="load">

Le fichier js plugin.js qui doit être chargé de manière asynchrone

export default function Mod(name) {
  this.name = name;
}
Mod.prototype.hi = function() {
  console.log('Hi~ ' + this.name);
};
Fichier de compilation d'entrée de

webpack Entry.js

let demo = false;

let btn = document.querySelector('.btn');
btn.addEventListener('click', function() {//1、点击按钮btn时
   require.ensure([], function(require) {
      let mod = require('./bundles/plugin.js').default;//2、异步栽入plugin.js
      if (!demo) {
         demo = new mod('jackson'); //3、创建新实例并禁止多次重复创建
      }
      demo.hi();//4、触发该实例的方法
   }, 'mod1');//5、生成一个名字为mod1.js的异步chunk模块
});

L'effet est que mod1.js est chargé et inséré dans la tête lorsque vous cliquez dessus, mais il n'est pas chargé au début

Enfin, à propos de la configuration de webpack.config.js.

   output: {
      path: path.resolve(__dirname, './dist'),
      filename: 'js/[name].js',
      publicPath: './dist/', 
      chunkFilename: 'js/async/[name].js'
      }

path + chunkFilename est le chemin généré par le module asynchrone require.ensurei, mais ce n'est pas le chemin auquel le fichier html y fait référence

Le vrai chemin de référence est publicPath + chunkFilename, c'est-à-dire que si le html se trouve dans le répertoire racine du projet, alors le chemin où le html fait référence à ce module js asynchrone est : ./dist/js/async/[name] .js, mais si votre html Dans un dossier, tel que index/index.html, ou le chemin ci-dessus ne peut pas être référencé, vous devez modifier le publickPath en : '../dist/' et sortir du dossier d'index pour trouver ce module asynchrone

迷茫

J'ai rencontré un problème similaire récemment, permettez-moi de l'expliquer brièvement.
Lorsque webpack est mis à niveau vers 2, vos deuxième et troisième méthodes de crédit ne sont pas directement empaquetées dans main.js.
C'est-à-dire que pour les modules nécessaires au chargement sur le premier écran, le mode de chargement asynchrone ne peut plus être utilisé, mais peut être chargé à la demande.
Vous pouvez jeter un œil dans le fichier empaqueté. À l'exception de la première méthode, votre méthode de test n'a pas été empaquetée dans votre js.

Peter_Zhu

Que souhaitez-vous faire avec les deuxième et troisième méthodes d'écriture ? Vous souhaitez simuler la méthode d’écriture des spécifications AMD ou CMD ?

La spécification de module la plus courante est le module ES6 et la spécification commonJS de node.js, car il existe des différences dans les détails de chargement spécifiques, tels que le temps de chargement et les différentes manières de référencer les fichiers. Mais le but de l'utilisation de webpack est d'unifier différentes spécifications. Webpack regroupera tous les modules à l'avance, leur donnera respectivement un identifiant et les référencera par identifiant, de sorte qu'il n'y ait aucune différence entre le module ES6 et les spécifications CommonJS après la compilation du webpack. il en va de même pour les spécifications AMD et CMD.

Si l'affiche souhaite utiliser webpack pour implémenter le chargement différé de CMD, cette idée est fausse, car quelle que soit la méthode de chargement, ce que fait webpack est de regrouper tous les modules dont vous dépendez (ou dépendrez) dans un seul fichier, afin que le package correspondant puisse être trouvé par identifiant au moment de l'exécution, atténuant les différences entre les spécifications

为情所困

Je ne connais pas votre environnement spécifique. Mon propre environnement a été mis à niveau vers Webpack2 + React Router v4. Vous pouvez vous référer au document : https://reacttraining.cn/web/...

.

Vous devez d'abord coder et créer un composant Bundle pour charger les modules et fichiers de composants requis à la demande.

import React, { Component } from 'react'

class Bundle extends Component {
  constructor(props){
    super(props)
    this.state = {
      mod: null
    }
  }
  componentWillMount() {
    this.load(this.props)
  }
  componentWillReceiveProps(nextProps) {
    if (nextProps.load !== this.props.load) {
      this.load(nextProps)
    }
  }
  load(props) {
    this.setState({
      mod: null
    })
    props.load((mod) => {
      this.setState({
        // handle both es imports and cjs
        mod: mod.default ? mod.default : mod
      })
    })
  }
  render() {
    return this.props.children(this.state.mod)
  }
}

export default Bundle

Le code ci-dessus est copié du document et la méthode d'initialisation de l'état est modifiée. Si vous ne modifiez pas la méthode d'initialisation de l'état, vous devez utiliser babel-plugin-transform-class-properties.babel-plugin-transform-class-properties.

使用的时候包含三个个步骤

  • 导入Bundle模块

import Bundle from './bundle.js';
  • 异步加载

import loadHome  from 'bundle-loader?lazy!./components/Home';
  • 初始化

const Home = ({...props}) => (
  <Bundle load={loadHome}>
    {(Component) => Component? <Component {...props}/>: <p>Loading...</p>}
  </Bundle>
)

当然, 你还需要配置你的 .babelrcwebpack.config.js, 下面我给我我自己的, 你可以研究一下.

webpack.config.js

  module: {
    rules: [
      // Javascript模块加载器
      {
        test: /\.js|jsx$/,
        exclude: /(node_modules|bower_components)/,
        use: {
          loader: 'babel-loader',
          options: {
            cacheDirectory : true,
            presets: [
              ['es2015', {modules: false}]
            ],
            plugins: [
              'syntax-dynamic-import',
              'transform-async-to-generator',
              'transform-regenerator',
              'transform-runtime'
            ]
          }
        }
      },
      ...
    ]

.babelrc

{
  "presets": [
    "es2017",
    [
      "latest",
      {"es2015":{"modules": false}}
    ],
    "stage-0",
    "react"
  ],
  "plugins": [
    ["import",{"libraryName": "antd","style": true }],
    "react-hot-loader/babel"
  ]
}

还有公共块输出插件的配置

  plugins: [
    ...
    new webpack.optimize.CommonsChunkPlugin({
      name: ["vendor", "manifest"],
      filename: '[name].[hash].js',
      minChunks: 2
    }),
    ...
  ]

通过上述N个步骤后, 组件Home

Il y a trois étapes à utiliser🎜
  • 🎜Importer le module Bundle🎜
rrreee
  • 🎜Chargement asynchrone🎜
rrreee
  • 🎜Initialisation🎜
rrreee 🎜Bien sûr, vous devez également configurer votre .babelrc et votre webpack.config.js, je vais donner le mien ci-dessous, vous pouvez l'étudier.🎜 🎜webpack.config.js🎜 rrreee 🎜.babelrc🎜 rrreee 🎜Il y a aussi la configuration du plugin de sortie de bloc public🎜 rrreee 🎜Après avoir passé les N étapes ci-dessus, le composant Home peut être utilisé.🎜
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal