[英]Webpack 3 + babel only parsing when entry is NOT higher than ./webpack.config.js
我正在构建一个脚手架引擎来启动Django后端+ React前端站点。 我还采用了多页应用程序方法,而不是SPA,所以事情有点...不合常规。
我向您展示该脚手架的最终结果,因为问题似乎出在我的webpack或babel配置以及我给他们的输入组件的位置。
因此,首先,此文件结构确实起作用,react组件在Django的服务器上呈现精美。
node/
package.json
.babelrc
webpack.config.js
/src
/Home.js (<- the react component)
...
www/
manage.py
www/
templates/
home.html
dist/
home.js (<- webpack's output)
...
但是我更喜欢这样,其中组件更靠近django template.html文件:
node/
package.json
.babelrc
webpack.config.js
...
www/
manage.py
www/
templates/
home.html
react/
components/
containers/
Home.js (<- the react component)
dist/
home.js (<- webpack's output)
但是,我现在收到一个构建错误,当它看到JSX时会抱怨-好像babel根本没有将其填充。
我唯一更改的是该组件不再位于node /目录下(显然,我更新了webpack.config.js中的路径以反映这一点)
我认为这不是webpack找到正确路径的问题。 因为它正在读取模板目录中的组件,并且仍将分发包正确放置在dist目录中。 但这不是polyfilling,结果输出文件已损坏。 我不只是说它被丑化了,我是说它已经完全坏掉了(见下文)
甚至有可能做我想做的事情?
细节
当我运行'npm run build'来运行webpack时出现错误:
ERROR in ../www/www/templates/react/containers/HomeContainer.js
Module build failed: SyntaxError: Unexpected token (6:2)
4 | const Home = props => {
5 | return (
> 6 | <div>
babelrc
{
"presets": ["env", "react"]
}
webpack.config.js
const webpack = require('webpack'); //to access built-in plugins
const path = require('path');
// This one works
// let ent = "./HomeContainer.js"
// This one does NOT work
let ent = "../www/www/templates/react/containers/HomeContainer.js"
let out = "../www/www/static/dist/js/Home"
module.exports = {
entry: {
[out]: ent
},
output: {
filename: '[name].js',
path: path.resolve(__dirname, './'),
},
module: {
rules: [
{ test: /\.css$/, exclude: /node_modules/, use: 'css-loader' },
{ test: /\.scss$/, exclude: /node_modules/, use: 'sass-loader' },
{ test: /\.(js|jsx)$/, exclude: /node_modules/, loader: "babel-loader" }
],
},
plugins: [
new webpack.optimize.UglifyJsPlugin(),
],
}
的package.json
{
"name": "frontend",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo 'Error: no test specified' && exit 1",
"build": "webpack"
},
"keywords": [],
"author": "",
"license": "ISC",
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "^6.25.0",
"babel-loader": "^7.1.1",
"babel-preset-env": "^1.6.0",
"babel-preset-react": "^6.24.1",
"css-loader": "^0.28.4",
"node-sass": "^4.5.3",
"sass-loader": "^6.0.6",
"webpack": "^3.1.0"
},
"dependencies": {
"react": "^15.6.1",
"react-dom": "^15.6.1"
}
}
损坏的dist / home.js
!function(m){function t(e){if(n[e])return n[e].exports;var r=n[e]={i:e,l:!1,exports:{}};return m[e].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};t.m=m,t.c=n,t.d=function(m,n,e){t.o(m,n)||Object.defineProperty(m,n,{configurable:!1,enumerable:!0,get:e})},t.n=function(m){var n=m&&m.__esModule?function(){return m.default}:function(){return m};return t.d(n,"a",n),n},t.o=function(m,t){return Object.prototype.hasOwnProperty.call(m,t)},t.p="",t(t.s=0)}([function(m,t){throw new Error("Module build failed: SyntaxError: Unexpected token (6:2)\n\n[0m [90m 4 | [39m[36mconst[39m [33mHome[39m [33m=[39m props [33m=>[39m {\n [90m 5 | [39m\t[36mreturn[39m (\n[31m[1m>[22m[39m[90m 6 | [39m\t\t[33m<[39m[33mdiv[39m[33m>[39m\n [90m | [39m\t\t[31m[1m^[22m[39m\n [90m 7 | [39m\t\t\t[33m<[39m[33mh1[39m[33m>[39m[33mHome[39m page [36mfor[39m { window[33m.[39mprops[33m.[39mproject_title }[33m<[39m[33m/[39m[33mh1[39m[33m>[39m\n [90m 8 | [39m\t\t\t[33m<[39m[33mp[39m[33m>[39m[33mTo[39m edit [36mthis[39m page[33m,[39m you[32m'll find the react component at /frontend/src/root/Home.js</p>[39m\n [90m 9 | [39m\t\t[33m<[39m[33m/[39m[33mdiv[39m[33m>[39m[0m\n")}]);
起作用的dist / home.js
!function(e){function t(o){if(n[o])return n[o].exports;var r=n[o]={i:o,l:!1,exports:{}};return e[o].call(r.exports,r,r.exports,t),r.l=!0,r.exports}var n={};t.m=e,t.c=n,t.d=function(e,n,o){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:o})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=81)}([function(e,t){function n(){throw new Error("setTimeout has not been defined")}function o(){throw new Error("clearTimeout has not been defined")}function r(e){if(l===setTimeout)return setTimeout(e,0);if((l===n||!l)&&setTimeout)return l=setTimeout,setTimeout(e,0);try{return l(e,0)}catch(t){try{return l.call(null,e,0)}catch(t){return l.call(this,e,0)}}}function i(e){if(p===clearTimeout)return clearTimeout(e);if((p===o||!p)&&clearTimeout)return p=clearTimeout,clearTimeout(e);try{return p(e)}catch(t){try{return p.call(null,e)}catch(t){return p.call(this,e)}}}function a(){m&&f&&(m=!1,f.length?h=f.concat(h):v=-1,h.length&&s())}function s(){if(!m){var e=r(a);m=!0;for(var t=h.length;t;){for(f=h,h=[];++v<t;)f&&f[v].run();v=-1,t=h.length}f=null,m=!1,i(e)}}function u(e,t){this.fun=e,this.array=t}function c(){}var l,p,d=e.exports={};!function(){try{l="function"==typeof setTimeout?setTimeout:n}catch(e){l=n}try{p="function"==typeof clearTimeout?clearTimeout:o}catch(e){p=o}}();var f,h=[],m=!1,v=-1;d.nextTick=function(e){var t=new Array(arguments.length-1);if(arguments.length>1)for(var n=1;n<arguments.length;n++)t[n-1]=arguments[n];h.push(new u(e,t)),1!==h.length||m||r(s)},u.prototype.run=function(){this.fun.apply(null,this.array)},d.title="browser",d.browser=!0,d.env={},d.argv=[],d.version="",d.versions={},d.on=c,d.addListener=c,d.once=c,d.off=c,d.removeListener=c,d.removeAllListeners=c,d.emit=c,d.prependListener=c,d.prependOnceListener=c,d.listeners=function(e){return[]},d.binding=function(e){throw new Error("process.binding is not supported")},d.cwd=function(){return"/"},d.chdir=function(e){throw new Error("process.chdir is not supported")},d.umask=function(){return 0}},function(e,t,n){"use strict";(function(t){function n(e,t,n,r,i,a,s,u){if(o(t),!e){var c;if(void 0===t)c=new Error("Minified exception occurred; use the non-minified dev environment for the full error message and additional helpful warnings.");else{var l=[n,r,i,a,s,u],p=0;c=new Error(t.replace(/%s/g,function(){return l[p++]})),c.name="Invariant Violation"}throw c.framesToPop=1,c}}var o=function(e){};"production"!==t.env.NODE_ENV&&(o=function(e){if(void 0===e)throw new Error("invariant requires an error message argument")}),e.exports=n}).call(t,n(0))},function(e,t,n){"use strict";(function(t){var o=n(9),r=o;if("production"!==t.env.NODE_ENV){var i=function(e){for(var t=arguments.length,n=Array(t>1?t-1:0),o=1;o<t;o++)n[o-1]=arguments[o];var r=0,i="Warning: "+e.replace(/%s/g,function(){return n[r++]});"undefined"!=typeof console&&console.error(i);try{throw new Error(i)}catch(e){}};r=function(e,t){if(void 0===t)throw new Error("`warning(condition, format, ...args)` requires a warning message argument");if(0!==t.indexOf("Failed Composite propType: ")&&!e){for(var n=arguments.length,o=Array(n>2?n-2:0),r=2;r<n;r++)o[r-2]=arguments[r];i.apply(void 0,[t].concat(o))}}}e.exports=r}).call(t,n(0))},function(e,t,n){"use strict";function o(e){for(var t=arguments.length-1,n="Minified React error #"+e+"; visit http://facebook.github.io/react/docs/error-decoder.html?invariant="+e,o=0;o<t;o++)n+="&args[]="+encodeURIComponent(arguments[o+1]);n+=" for the full message or use the non-minified dev environment for full errors and additional helpful warnings.";var r=new Error(n);throw r.name="Invariant Violation",r.framesToPop=1,r}e.exports=o},function(e,t,n){"use strict";function o(e){if(null===e||void 0===e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}/*
问题是Babel会寻找最接近要.babelrc
文件的.babelrc 。 这意味着它将在文件目录中查找并开始爬升目录树,直到找到一个或到达文件系统的根目录为止。 但是,由于您的node
目录是www
的同级目录,因此您的源代码就位于该.babelrc
,因此找不到.babelrc
,因此不会应用您的预设。
您可以在babel-loader
上配置选项 ,无论使用什么目录,都可以使用这些选项 。 不幸的是,您会遇到模块分辨率问题,默认情况下该模块与Node模块分辨率相同。 导入模块后,将在node_modules
目录中搜索该node_modules
,如果在该目录中找不到该模块,则它将在父目录(即../node_modules
)中../node_modules
,依此类推。 这与Babel使用的行为相同,并且在Node中的工具中非常常见。
可以将预设导入配置中,因此不会从正在编译的文件中解析这些预设。
{
test: /\.(js|jsx)$/,
exclude: /node_modules/,
loader: 'babel-loader',
options: {
presets: [
// Need to require them, so they are resolved from this config,
// otherwise they are resolved from the directory of the file that
// is being transpiled.
require('babel-preset-env'),
require('babel-preset-react')
]
}
}
除此之外,您还将面临解决使用npm安装的任何模块的问题,因为它们再次位于同级目录中,并且找不到。 的WebPack允许您解决与resolve.module
。
resolve: {
modules: [
// Also look for modules next to the webpack config, because dependencies
// like `react` are installed here, not where the components are.
path.resolve(__dirname, 'node_modules'),
'node_modules'
],
}
即使可行,我还是强烈建议您不要采用这种结构。 毕竟,这是webpack中的一种解决方法,如果您想添加任何其他工具,则很可能会遇到问题。
最重要的部分是节点模块应位于项目的根目录中,而要使用它们的任何内容都将位于子目录中。 像这样:
.
├─ .babelrc
├─ manage.py
├─ package.json
├─ webpack.config.js
└─ www
├─ dist
│ └─ bundle.js
└─ templates
├─ home.html
└─ react
├─ components
└─ containers
└─ Home.js
这样一来,您无需进行任何处理,就可以确保从npm安装的任何模块都可以使用。 此外,无论项目是安装npm软件包,运行webpack还是运行python构建,您都可以从项目的根目录运行所有内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.