Skip to content

Commit

Permalink
Merge branch 'feature/detachWebpack'
Browse files Browse the repository at this point in the history
Fix #35
Fix #44
  • Loading branch information
tamorim committed Sep 24, 2015
2 parents 697a283 + ca538da commit 6f50002
Show file tree
Hide file tree
Showing 8 changed files with 223 additions and 196 deletions.
18 changes: 18 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
### v0.9.0 (2015-09-24)

Let's kick the dust off and start with the good stuff!

The file `vtex-webpack` is now **gone** (we won't miss you, so k bye). Now we have a new one, shiny and pretty called `webpack` (yep), it lives on the `lib` folder.

The logic behind the `-w` and `-s` options is now there, and the entrypoint for them is now on `vtex-watch`, which makes much more sense since they are options of **watch**.

Last but not least, the VTEX Toolbelt server now uses the new [react-transform](https://github.com/gaearon/react-transform)!

Instead of using `webpack-dev-server `, we're using an `express` server with `webpack-hot-middleware` and `webpack-dev-middleware`. Note that `webpack-dev-middleware` doesn't write anything on disk and handles everything in memory, so don't freak out if you see your `assets` folder sitting there all alone.

This assumes some pre-configuration on the project to work properly (see [Hot Module Replacement](https://github.com/vtex/toolbelt#hot-module-replacement) section on README). Besides, it's a world of new possibilities and probably makes it easier to make the dreamy multiple app hot reload that we all want!

On this release two main issues are fulfilled (actually, one is partially done):

- [`#44`](https://github.com/vtex/toolbelt/issues/44) (this is the partially one)
- [`#35`](https://github.com/vtex/toolbelt/issues/35)
21 changes: 21 additions & 0 deletions LICENSE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
The MIT License (MIT)

Copyright (c) 2015 VTEX

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
117 changes: 43 additions & 74 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

CLI tool for developing VTEX apps.


# Getting started

The VTEX Toolbelt can be installed via [npm](https://www.npmjs.com/).
Expand Down Expand Up @@ -67,6 +68,7 @@ You can use `vtex login` to login with yout VTEX ID credentials or `vtex logout`
Note that `watch` and `publish` implicitly checks if you're logged, and if you're not, it asks your credentials before proceeding.
# Watch
To develop an app locally, open the directory where your VTEX app is and then type:
Expand Down Expand Up @@ -96,87 +98,66 @@ Make sure that you have a well configured and working [webpack.config.js](http:/
vtex watch --webpack <sandbox-name>
```

## Webpack Dev Server
## Dev Server

You can also run the VTEX Toolbelt watcher in parallel with the [Webpack Dev Server](http://webpack.github.io/docs/webpack-dev-server.html) watcher if you use the `--server` option under the `watch` command.
You can also run the VTEX Toolbelt watcher in parallel with the Dev Server watcher if you use the `--server` option under the `watch` command.

As Webpack Dev Server uses Webpack, you also need a webpack.config.js file on the root of yout project.
As Dev Server uses Webpack, you also need a webpack.config.js file on the root of yout project.

```sh
vtex watch --server <sandbox-name>
```

You need to call it this way if you want to enable [Hot Module Replacement](http://webpack.github.io/docs/hot-module-replacement-with-webpack.html), see below for more information on how to configure your project and OS in order to make it work properly.
You need to call it this way if you want to enable [Hot Module Replacement](http://webpack.github.io/docs/hot-module-replacement-with-webpack.html), see below for more information on how to configure your project for this.


# Livereload

Add to your layout the following script:

```html
<script src="http://localhost:35729/livereload.js?snipver=1"></script>
<script src="http://localhost:35729/livereload.js?snipver=1"></script>
```

# Hot Module Replacement

In order to make the Hot Module Replacement work, besides running the `watch` command with the `--server` option, you need to:

## Edit your hosts file

The hosts file is a computer file used by an operating system to map hostnames to IP addresses.

On Linux and Mac you can find the file on `/etc/hosts`, you need `sudo` to be able to edit this file.
On Windows you can find it on `C:\Windows\System32\Drivers\etc\hosts`, you may need administrative privileges to edit the file.

Append to the end of your file the following:

```plain
127.0.0.1 <name-of-your-store>.beta.myvtex.com
```

127.0.0.1 is your localhost. It may vary on different machines.

## Add this snippet to your Webpack entry point

```javascript
// Enable react hot loading with external React
if (module.hot) {
window.RootInstanceProvider = require('react-hot-loader/Injection').RootInstanceProvider;
}
```

For more on that matter, see [this](https://github.com/gaearon/react-hot-loader/tree/master/docs#usage-with-external-react).

## Configure your Webpack config file

You need to add to your webpack.config.js file the options that Webpack Dev Server uses in order to work, it can be something like:

```javascript
devServer: {
publicPath: publicPath,
port: 3000,
hot: true,
inline: true,
stats: {
assets: false,
colors: true,
version: true,
hash: false,
timings: true,
chunks: true,
chunkModules: false
},
historyApiFallback: true,
proxy: {
'*': 'http://janus-edge.vtex.com.br/'
First things first, you need to use [babel](https://babeljs.io/). Then, there's a few packages you need to install:

- [babel-plugin-react-transform](https://github.com/gaearon/babel-plugin-react-transform)
- [react-transform-hmr](https://github.com/gaearon/react-transform-hmr)
- [react-transform-catch-errors](https://github.com/gaearon/react-transform-catch-errors) (actually, this one is opcional)

You can install them using `npm i <package-name> --save-dev` on the root folder of your project (the `--save-dev` adds that package to the `devDependencies` of your `package.json`).

After that, create a `.babelrc` file on the root folder of your project with the following:

```json
{
"stage": 0,
"env": {
"development": {
"plugins": ["react-transform"],
"extra": {
"react-transform": {
"transforms": [{
"transform": "react-transform-hmr",
"imports": ["react"],
"locals": ["module"]
}, {
"transform": "react-transform-catch-errors",
"imports": ["react", "redbox-react"]
}]
}
}
}
}
}
```

For more on that, you can see [this](http://webpack.github.io/docs/webpack-dev-server.html#webpack-dev-server-cli).
Presto! Everything is configured and ready to use. Remember to use the following URL while running `vtex watch -s <sandbox-name>`:

That should do it! Remember to open the URL that you defined with the port configured in your webpack.config file.
`<store-name>.local.myvtex.com:3000`

Unfortunately to access the URL normally, you need to comment or delete the line added in your hosts file.

# VTEX Ignore

Expand All @@ -185,10 +166,12 @@ The VTEX Ignore it's a file that you can put on the root of your project, naming
This files tells `watch` which files he shouldn't send to the server.
If no `.vtexignore` is found, it fallbacks to the [.gitignore](http://git-scm.com/docs/gitignore) file.


# Publish

To publish your VTEX app to VTEX Gallery, just type `vtex publish`. The app will be published under the vendor name.


# Troubleshooting

### Cannot resolve module 'react/lib/ReactMount'
Expand All @@ -210,21 +193,7 @@ externals: {
},
```

### Multiple entry points not hot reloading

If you have multiple entry points, you should include `webpack/hot/only-dev-server` on each entry, like so:
## License

```js
entry: hot ? {
'.':
[
'webpack-dev-server/client?http://0.0.0.0:3000',
'webpack/hot/only-dev-server',
'./src/' + pkg.name + '.jsx'
],
editor:
[
'webpack/hot/only-dev-server',
'./src/' + pkg.name + '-editor.jsx'
]
```
MIT
9 changes: 6 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
"vtex-login": "lib/vtex-login.js",
"vtex-logout": "lib/vtex-logout.js",
"vtex-watch": "lib/vtex-watch.js",
"vtex-publish": "lib/vtex-publish.js",
"vtex-webpack": "lib/vtex-webpack.js"
"vtex-publish": "lib/vtex-publish.js"
},
"scripts": {
"start": "node lib/vtex.js",
Expand Down Expand Up @@ -36,7 +35,9 @@
"chalk": "^1.0.0",
"chokidar": "^1.0.0-rc4",
"docopt": "^0.6.2",
"express": "^4.13.3",
"glob": "^5.0.3",
"http-proxy": "^1.11.2",
"node-libs-browser": "^0.5.2",
"prompt": "~0.2.14",
"q": "~1.2.0",
Expand All @@ -47,7 +48,9 @@
"tiny-lr": "^0.1.5",
"vtexsay": "^1.0.3",
"webpack": "^1.10.1",
"webpack-dev-server": "^1.10.1"
"webpack-dev-middleware": "^1.2.0",
"webpack-dev-server": "^1.10.1",
"webpack-hot-middleware": "^2.2.0"
},
"preferGlobal": true,
"devDependencies": {
Expand Down
100 changes: 100 additions & 0 deletions src/lib/webpack.coffee
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
webpack = require 'webpack'
express = require 'express'
httpProxy = require 'http-proxy'
path = require 'path'
net = require 'net'
chalk = require 'chalk'

class WebpackOption
constructor: ->
try
@config = require process.cwd() + '/webpack.config.js'
catch err
if err.code is 'MODULE_NOT_FOUND'
pkgName = err.toString().match(/'(.*)'/)[1]

if pkgName.indexOf('webpack.config.js') isnt -1
console.log 'webpack.config.js not found'.bold.yellow
else
console.log err.toString().bold.red
console.log "Did you installed #{pkgName.yellow}?"

process.exit 1

@compiler = webpack @config
@DELAY_TIME = 2000

startDevServer: =>
runDevServer = =>
setTimeout =>
proxy = new httpProxy.createProxyServer()
app = express()
app.use require('webpack-dev-middleware')(@compiler,
noInfo: true
publicPath: @config.output.publicPath
)
app.use require('webpack-hot-middleware')(@compiler)

if @config.proxy
if !Array.isArray @config.proxy
@config.proxy = Object.keys(@config.proxy).map (path) =>
if typeof @config.proxy[path] is 'string'
proxyOptions = path: path, target: @config.proxy[path]
else
proxyOptions = @config.proxy[path]
proxyOptions.path = path

proxyOptions

@config.proxy.forEach (proxyOptions) ->
app.all proxyOptions.path, (req, res) ->
if typeof proxyOptions.rewrite is 'function'
proxyOptions.rewrite req, proxyOptions

if proxyOptions.host
req.headers.host = proxyOptions.host

proxy.web req, res, proxyOptions, (err) =>
msg = "cannot proxy to #{proxyOptions.target} (#{err.message})"
res.statusCode = 502
res.end()

if proxyOptions.configure
proxyOptions.configure proxy

app.listen 3000, 'localhost', (err) =>
if err
console.log err
return
console.log 'Listening at http://localhost:3000'
, @DELAY_TIME

testPort = net.createServer()
.once 'error', (err) ->
if err.code is 'EADDRINUSE'
console.log "#{'ERROR:'.bold.red} Server port #{port} already in use"
console.log "(maybe another `vtex watch -s` is running?)"
process.exit 1
.once 'listening', ->
testPort.close()
runDevServer()
.listen 3000

startWebpack: =>
setTimeout =>
@compiler.watch {}, (err, stats) ->
if err
console.error err.stack || err
return

outputOptions =
cached: false
cachedAssets: false
colors: require 'supports-color'
exclude: ["node_modules", "bower_components", "jam", "components"]

console.log stats.toString(outputOptions) + '\n'
, @DELAY_TIME

module.exports = new WebpackOption

Loading

0 comments on commit 6f50002

Please sign in to comment.