Sass 无法使webpack完全忽略不必要的JSX组件
为了一个项目,我花了几年时间锁定在一个古老的技术堆栈中,终于有机会探索更多的最新框架,并深入了解React和Webpack。到目前为止,这在很大程度上是一次令人耳目一新和愉快的经历,但我在使用网页时遇到了一些困难,我希望蜂巢思维能够帮助解决这些问题 我一直在仔细阅读Webpack2.0文档,搜索得非常彻底,结果很短(我只找到了一个问题,很接近,但我不确定它是否适用)。由于缺乏信息,我认为我正在考虑以下两种情况之一:Sass 无法使webpack完全忽略不必要的JSX组件,sass,webpack,extract-text-plugin,Sass,Webpack,Extract Text Plugin,为了一个项目,我花了几年时间锁定在一个古老的技术堆栈中,终于有机会探索更多的最新框架,并深入了解React和Webpack。到目前为止,这在很大程度上是一次令人耳目一新和愉快的经历,但我在使用网页时遇到了一些困难,我希望蜂巢思维能够帮助解决这些问题 我一直在仔细阅读Webpack2.0文档,搜索得非常彻底,结果很短(我只找到了一个问题,很接近,但我不确定它是否适用)。由于缺乏信息,我认为我正在考虑以下两种情况之一: 我想做的是疯狂的 我想做的是基本的,不需要动脑筋 …然而,我在这里 我正在寻找的
- 项目包含一个组件桶,这些组件可以组装成一个页面,并根据配置文件给出一个主题
- 每个组件都包含自己的模块化CSS,用SASS编写
- 每个导出的页面都是静态的,包实际上会从导出目录中删除。(是的,如果项目结束时只是呈现一系列单一的、静态的页面,那么React有点过分了。项目的未来状态将包括一个UI,而React应该非常适合这个UI,因此最好现在就用JSX编写这些组件。)
- CSS是使用
从捆绑包中提取的-在最终导出中,没有样式直接内联到元素上,这不是可以更改的要求extract text webpack plugin
- 作为页面主题信息的一部分,将设置SASS变量,然后SASS将这些变量用于每个JSX组件
- 只有在给定页面的配置文件中引用的JSX组件的SASS变量才被编译并通过
传递,以便在编译CSS时使用SASS加载程序
组件1
,组件2
,组件3
,等等。其中每一个都有一个与其关联的匹配的.scss
文件,包括以下方式:
import React from 'react';
import styles from './styles.scss';
module.exports = React.createClass({
propTypes: {
foo: React.PropTypes.string.isRequired,
},
render: function () {
return (
<section className={`myClass`}>
<Stuff {...props} />
</section>
);
},
});
load_components() {
let component_templates = {};
let get_component = function(component_name) {
return require(`../path/to/components/${component_name}/template.jsx`);
}
for (let i = 0; i < this.included_components.length; i++) {
let component = this.included_components[i];
component_templates[component] = get_component(component);
}
return component_templates;
}
上面迭代了一个对象,该对象包含我所需的JSX组件(对于给定的页面),该对象现在是以以下方式创建的:
import React from 'react';
import styles from './styles.scss';
module.exports = React.createClass({
propTypes: {
foo: React.PropTypes.string.isRequired,
},
render: function () {
return (
<section className={`myClass`}>
<Stuff {...props} />
</section>
);
},
});
load_components() {
let component_templates = {};
let get_component = function(component_name) {
return require(`../path/to/components/${component_name}/template.jsx`);
}
for (let i = 0; i < this.included_components.length; i++) {
let component = this.included_components[i];
component_templates[component] = get_component(component);
}
return component_templates;
}
那里的exclude
条目是新的,似乎不起作用
这是一部中篇小说,但我想在信息太多方面犯错误,而不是信息太少。我是错过了一些简单的事情,还是试图做一些疯狂的事情?两者都有
如何使未使用的组件不被Webpack处理?TL;博士
不要在require
中使用表达式,并使用多个入口点,每个页面一个入口点
详细答案 Webpack似乎希望捆绑项目文件夹中的所有内容 事实并非如此,webpack只包含您导入的内容,这是静态确定的。事实上,很多刚接触webpack的人一开始都很困惑,webpack不仅仅包含整个项目。但在你的情况下,你遇到了一个边缘案件。问题在于您使用
require
的方式,特别是此功能:
let get_component = function(component_name) {
return require(`../path/to/components/${component_name}/template.jsx`);
}
您正在尝试根据参数将组件导入函数。webpack如何在编译时知道应该包含哪些组件?嗯,webpack不做任何程序流分析,因此唯一的可能性是包含所有可能与表达式匹配的组件
您很幸运,webpack首先允许您这样做,因为只向require
传递一个变量将失败。例如:
function requireExpression(component) {
return require(component);
}
requireExpression('./components/a/template.jsx');
将在编译时向您发出此警告,即使很容易看出需要哪些组件(稍后在运行时失败):
但因为webpack不做程序流分析,所以它看不到这一点,即使它做了,你也可以在任何地方使用该功能,即使用户输入,这基本上是一个失败的原因
有关更多详细信息,请参阅官方文件
Webpack试图包含我们的所有组件,而不管实际加载的布局是什么
既然您知道了为什么webpack需要所有组件,那么理解为什么您的想法行不通,坦白说,过于复杂也很重要
如果我理解正确的话,您有一个多页应用程序,其中每个页面都应该有一个单独的包,其中只包含必要的组件。但是您真正要做的是在运行时只使用所需的组件,所以从技术上讲,您有一个包含所有页面的包,但您只使用其中一个,这对于单页面应用程序(SPA)来说是非常好的。不知何故,您希望webpack知道您正在使用哪一个,它只能通过运行它才能知道,所以在编译时它肯定无法知道
问题的根源在于您在运行时(在程序的执行过程中)做出决策,而应该在编译时进行决策。解决方案是使用多个入口点,如中所示。你所知道的
Critical dependency: the request of a dependency is an expression
entry: {
pageOne: './src/pageOne.jsx',
pageTwo: './src/pageTwo.jsx',
// ...
},
output: {
filename: '[name].bundle.js'
}