Hi @gauravtiwari @dhh!
First of all thanks for this gem :)
Hope you can help me with my problem:
I'm getting an "Unexpected token import" on my browser after webpack successfully compiles everything down. Haven't been able to trace back the problem even after a clean reinstall and restart of my project. I am trying to implement a project that I previously created using React-Boilerplate as as a base.
Here's my webpack log:
16:48:41 webpacker.1 | Hash: 1d36acb323e794b2c6b5
16:48:41 web.1 | Started GET "/" for ::1 at 2017-07-05 16:48:41 -0500
16:48:41 webpacker.1 | Version: webpack 3.0.0
16:48:41 web.1 | Processing by StaticController#index as HTML
16:48:41 webpacker.1 | Time: 2004ms
16:48:41 web.1 | Rendering static/index.html.erb within layouts/application
16:48:41 webpacker.1 | Asset Size Chunks Chunk Names
16:48:41 web.1 | Rendered static/index.html.erb within layouts/application (4.8ms)
16:48:41 webpacker.1 | manifest.json 720 bytes [emitted]
16:48:41 webpacker.1 | 1.js 376 kB 1 [emitted] [big]
16:48:41 webpacker.1 | application.js 5.3 MB 5 [emitted] [big] application
16:48:41 webpacker.1 | [417] ./app/javascript/packs/application.js 7.11 kB {5} [built]
16:48:41 webpacker.1 | [704] ./node_modules/react-router-dom/es/Link.js 3.82 kB {5} [built]
16:48:41 webpacker.1 | [705] ./node_modules/react-router-dom/es/index.js 925 bytes {5} [built]
16:48:41 webpacker.1 | [706] ./node_modules/react-router-dom/es/BrowserRouter.js 2.12 kB {5} [built]
16:48:41 webpacker.1 | [708] ./node_modules/react-router-dom/es/HashRouter.js 2.1 kB {5} [built]
16:48:41 webpacker.1 | [710] ./node_modules/react-router-dom/es/MemoryRouter.js 55 bytes {5} [built]
16:48:41 web.1 | Completed 200 OK in 51ms (Views: 48.0ms)
16:48:41 webpacker.1 | [711] ./node_modules/react-router-dom/es/NavLink.js 2.48 kB {5} [built]
16:48:41 web.1 |
16:48:41 webpacker.1 | [712] ./node_modules/react-router-dom/es/Prompt.js 49 bytes {5} [built]
16:48:41 web.1 |
16:48:41 webpacker.1 | [713] ./node_modules/react-router-dom/es/Redirect.js 51 bytes {5} [built]
16:48:41 webpacker.1 | [714] ./node_modules/react-router-dom/es/Route.js 48 bytes {5} [built]
16:48:41 webpacker.1 | [715] ./node_modules/react-router-dom/es/Router.js 49 bytes {5} [built]
16:48:41 webpacker.1 | [716] ./node_modules/react-router-dom/es/StaticRouter.js 55 bytes {5} [built]
16:48:41 webpacker.1 | [717] ./node_modules/react-router-dom/es/Switch.js 49 bytes {5} [built]
16:48:41 webpacker.1 | [718] ./node_modules/react-router-dom/es/matchPath.js 52 bytes {5} [built]
16:48:41 webpacker.1 | [719] ./node_modules/react-router-dom/es/withRouter.js 53 bytes {5} [built]
16:48:41 webpacker.1 | + 692 hidden modules
16:48:41 webpacker.1 | webpack: Compiled successfully.
In my browser:
Uncaught SyntaxError: Unexpected token import
at Object.<anonymous> (application.js:6600)
at __webpack_require__ (application.js:50)
at eval (webpack-internal:///417:191)
at Object.<anonymous> (application.js:5028)
at __webpack_require__ (application.js:50)
at Object.<anonymous> (application.js:5015)
at __webpack_require__ (application.js:50)
at application.js:145
at application.js:148
The pack I'm trying to load:
/**
* app.js
*
* This is the entry file for the application, only setup and boilerplate
* code.
*/
// Needed for redux-saga es6 generator support
import 'babel-polyfill';
// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { applyRouterMiddleware, Router } from 'react-router';
import { BrowserRouter } from 'react-router-dom'
import { syncHistoryWithStore } from 'react-router-redux';
// import 'sanitize.css/sanitize.css';
// Import root app
import App from '../Bot/containers/App';
// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from '../Bot/containers/App/selectors';
// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-unresolved, import/extensions */
import '!file-loader?name=[name].[ext]!../Bot/favicon.ico';
import '!file-loader?name=[name].[ext]!../Bot/manifest.json';
import 'file-loader?name=[name].[ext]!../Bot/.htaccess';
/* eslint-enable import/no-unresolved, import/extensions */
import configureStore from '../Bot/store';
// Import i18n messages
import { translationMessages } from '../Bot/i18n';
// Import CSS reset and Global Styles
import '../Bot/global-styles';
// Import root routes
import createRoutes from '../Bot/routes';
// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
// e.g. `const browserHistory = useRouterHistory(createBrowserHistory)();`
const initialState = {};
const store = configureStore(initialState, BrowserRouter);
// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
const history = syncHistoryWithStore(BrowserRouter, store, {
selectLocationState: makeSelectLocationState(),
});
// Set up the router, wrapping all Routes in the App component
const rootRoute = {
component: App,
childRoutes: createRoutes(store),
};
const render = () => {
ReactDOM.render(
<Provider store={store}>
<Router
history={history}
routes={rootRoute}
/>
</Provider>,
document.getElementById('app')
);
};
// Hot reloadable translation json files
if (module.hot) {
// modules.hot.accept does not accept dynamic dependencies,
// have to be constants at compile-time
module.hot.accept('../Bot/i18n', () => {
render(translationMessages);
});
}
// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
(new Promise((resolve) => {
resolve(import('intl'));
}))
.then(() => Promise.all([
import('intl/locale-data/jsonp/en.js'),
]))
.then(() => render(translationMessages))
.catch((err) => {
throw err;
});
} else {
render(translationMessages);
}
// Install ServiceWorker and AppCache in the end since
// it's not most important operation and if main code fails,
// we do not want it installed
if (process.env.NODE_ENV === 'production') {
require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
My .babelrc:
{
"presets": [
[
"env",
{
"modules": false,
"targets": {
"browsers": "> 1%",
"uglify": true
},
"useBuiltIns": true
}
],
"react"
],
"plugins": [
"syntax-dynamic-import",
"transform-object-rest-spread",
[
"transform-class-properties",
{
"spec": true
}
]
]
}
@CharlieIGG Are you sure it's rendering compiled application.js? Are you using ./bin/webpack-dev-server or ./bin/webpack?
Perhaps run this ./bin/webpack-dev-server in separate terminal tab and then rails server in another. Then, open up the browser and see if it's still same. I am suspecting it's using uncompiled pack in your case - may be you copied it over earlier to packs directory inside public/packs?
Or the other way around. You haven't change any settings inside webpacker.yml right?
Perhaps run this ./bin/webpack-dev-server in separate terminal tab and then rails server in another.
I'm running both simultaneously with Foreman, but I just tried them separately and still got the same result.
may be you copied it over earlier to packs directory inside public/packs? Or the other way around. You haven't change any settings inside webpacker.yml right?
None of these, haven't touched either.
Also I just realized that if I load the example 'hello_react' module instead of my react app it does load, even though that example uses 'import':
<%= javascript_pack_tag 'hello_react' %>
It appears to be something related to my react app or the dependencies it has, but after hours of fiddling around I haven't been able to trace it. Any pointers of how I might be able to trace/debug this are super welcome @gauravtiwari. Thanks for all your help.
Could you paste your browser logs please? I mean the rendered HTML inside elements tab - see what url it's using. What you have inside public/packs? Could you please open up and check the compiled files?
Here's what's rendered:
<html>
<head>
...
</head>
<body>
<script src="http://0.0.0.0:8080/packs/bot.js"></script>
</body>
</html>
What you have instead public/packs? Could you please open up and check the compiled files?
All I have inside public/packs is a manifest.json file which has the following content:
{
".htaccess": "http://0.0.0.0:8080/packs/.htaccess.bin",
"0.js": "http://0.0.0.0:8080/packs/0.js",
"1.js": "http://0.0.0.0:8080/packs/1.js",
"2.js": "http://0.0.0.0:8080/packs/2.js",
"3.js": "http://0.0.0.0:8080/packs/3.js",
"4.js": "http://0.0.0.0:8080/packs/4.js",
"bot.js": "http://0.0.0.0:8080/packs/bot.js",
"favicon.ico": "http://0.0.0.0:8080/packs/favicon.ico",
"hello_react.js": "http://0.0.0.0:8080/packs/hello_react.js",
"linkIcon2.svg": "http://0.0.0.0:8080/packs/linkIcon2.svg",
"manifest.json": "http://0.0.0.0:8080/packs/manifest.json",
"refreshWhite.svg": "http://0.0.0.0:8080/packs/refreshWhite.svg",
"sendWhite.svg": "http://0.0.0.0:8080/packs/sendWhite.svg"
}
Am I supposed to see the actual compiled files inside this folder?
Why you got .htaccess there? 馃槃 Webpack shouldn't compile that
Anyway, so looks like it compiles and renders correct file. Do you have import statements inside the bot.js file i.e. inside public/packs/bot.js?
Why you got .htaccess there? 馃槃 Webpack shouldn't compile that
The React-Boilerplate project does this, I just copied that over 馃槼
Do you have import statements inside the bot.js file i.e. inside public/packs/bot.js?
Yes I do, my logic was that if hello_react.jsx could use them and work fine, then my bot.jsshould work. Am I missing something here?
AHA! I just realized I cannot import relative path components in hello_react.jsxeither, I get the same error.
I'm confused here. How should I structure and communicate my files then? I have:
-app/
--javascript/
---Bot/ <----- All my react components live here
---packs/
----bot.js <----- I'm loading this via javascript_pack_tag, so I'd like to call my components here.
----hello_react.jsx
Thanks for helping this newbie @gauravtiwari !
@CharlieIGG You can do it like so:
import SomeComponent from '../Bot/some_component.js'
That's exactly what I'm doing (minus the file extension):
// Needed for redux-saga es6 generator support
import 'babel-polyfill';
// Import all the third party stuff
import React from 'react';
import ReactDOM from 'react-dom';
import { Provider } from 'react-redux';
import { applyRouterMiddleware, Router, browserHistory } from 'react-router';
import { syncHistoryWithStore } from 'react-router-redux';
// Import root app
import App from '../Bot/containers/App';
// Import selector for `syncHistoryWithStore`
import { makeSelectLocationState } from '../Bot/containers/App/selectors';
// Load the favicon, the manifest.json file and the .htaccess file
/* eslint-disable import/no-unresolved, import/extensions */
import '!file-loader?name=[name].[ext]!../Bot/favicon.ico';
import '!file-loader?name=[name].[ext]!../Bot/manifest.json';
/* eslint-enable import/no-unresolved, import/extensions */
import configureStore from '../Bot/store';
// Import i18n messages
import { translationMessages } from '../Bot/i18n';
// Import CSS reset and Global Styles
import '../Bot/global-styles';
// Import root routes
import createRoutes from '../Bot/routes';
// Create redux store with history
// this uses the singleton browserHistory provided by react-router
// Optionally, this could be changed to leverage a created history
// e.g. `const browserHistory = useRouterHistory(createBrowserHistory)();`
const initialState = {};
const store = configureStore(initialState, browserHistory);
// Sync history and store, as the react-router-redux reducer
// is under the non-default key ("routing"), selectLocationState
// must be provided for resolving how to retrieve the "route" in the state
const history = syncHistoryWithStore(browserHistory, store, {
selectLocationState: makeSelectLocationState(),
});
// Set up the router, wrapping all Routes in the App component
const rootRoute = {
component: App,
childRoutes: createRoutes(store),
};
const render = () => {
ReactDOM.render(
<Provider store={store}>
<Router
history={history}
routes={rootRoute}
render={
// Scroll to top when going to a new page, imitating default browser
// behaviour
applyRouterMiddleware(useScroll())
}
/>
</Provider>,
document.getElementById('app')
);
};
// Hot reloadable translation json files
if (module.hot) {
// modules.hot.accept does not accept dynamic dependencies,
// have to be constants at compile-time
module.hot.accept('../Bot/i18n', () => {
render(translationMessages);
});
}
// Chunked polyfill for browsers without Intl support
if (!window.Intl) {
(new Promise((resolve) => {
resolve(import('intl'));
}))
.then(() => Promise.all([
import('intl/locale-data/jsonp/en.js'),
]))
.then(() => render(translationMessages))
.catch((err) => {
throw err;
});
} else {
render(translationMessages);
}
// Install ServiceWorker and AppCache in the end since
// it's not most important operation and if main code fails,
// we do not want it installed
if (process.env.NODE_ENV === 'production') {
require('offline-plugin/runtime').install(); // eslint-disable-line global-require
}
@CharlieIGG Could you please check public/packs/bot.js file and see if it's compiled? or localhost:8080/packs/bot.js in browser and see what you get (if using dev-server)? I am unsure why the pack isn't compiled
public/packs/bot.js
No such file in public/packs, just the manifest.json
localhost:8080/packs/bot.js
Here the code does show up apparently compiled
@CharlieIGG Could you try in incognito mode please?
Yeah, same thing, also across different browsers.
The issue seems only limited to importing relative file paths from a file inside app/javascript/packs
If this file is compiled - localhost:8080/packs/bot.js then why there is error in the browser? You still getting the same import error?
You still getting the same import error?
Yes I am
If I try to import anything from the app/javascript/Bot/ folder into any file inside app/javascript/packs/ I get the error.
For instance importing some_component into the hello_react.jsx file, like this:
import SomeComponent from '../Bot/some_component.js'

@gauravtiwari I erased all my React-Boilerplate code, and created some simpler components, and now the Import problem is gone.
I'd still love to be able to integrate React-Boilerplate with webpacker for several reasons, but apparently this won't work as of now and I have no clue why.
RBp is a very popular base, so it might be worth it to look into how to make these two work together, but I'm closing this issue as of now in order to not further waste your time. Thanks!
@CharlieIGG Alright I will push an example app with RB 馃憤 No worries
@CharlieIGG Your issue is related to this - https://github.com/webpack/webpack/issues/4857
Anyway pushed a working example for you here - https://github.com/gauravtiwari/webpacker-react-boilerplate
To run locally:
git clone [email protected]:gauravtiwari/webpacker-react-boilerplate.git
cd webpacker-react-boilerplate
yarn
bundle
gem install foreman
foreman start
Also pushed it to Heroku: https://aqueous-retreat-72659.herokuapp.com/
Okay @gauravtiwari you're a rockstar, thanks for this!
I can confirm your example is working for me. I'll see if I can adapt my code using this.
TYVM!
Copy-pasted my component/actions/reducers and routes to your example and now everything works @gauravtiwari. This is still super-puzzling for me since I see no major differences but this is great! TYVM again!
@CharlieIGG Great, no problem 馃憤 Actually react-boilerplate has similar setup as Webpacker so there are some conflicting concerns. It won't be straight drop-in usage.
FYI, main files changed were:
.babelrc (installed two plugins for dynamic import)
.yarn.lock
package.json (installed two plugins)
Everything else is same. You would probably need to add webpack offline plugin inside config/webpack/production.js since Webpacker doesn't ship with it - https://github.com/NekR/offline-plugin
Most helpful comment
Also pushed it to Heroku: https://aqueous-retreat-72659.herokuapp.com/