Maison > Questions et réponses > le corps du texte
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 ?
淡淡烟草味2017-05-19 10:28:20
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
迷茫2017-05-19 10:28:20
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.
天蓬老师2017-05-19 10:28:20
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.
为情所困2017-05-19 10:28:20
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>
)
当然, 你还需要配置你的 .babelrc
和 webpack.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
Bundle
🎜.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é.🎜