簡體   English   中英

Webpack 3 + babel僅在條目不高於./webpack.config.js時進行解析

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM