Skip to content

Commit

Permalink
Merge pull request #31 from accurat/webpack-updates
Browse files Browse the repository at this point in the history
Various webpack updates
  • Loading branch information
caesarsol authored Sep 14, 2017
2 parents aa9f2f7 + 015073c commit 7b80b3f
Show file tree
Hide file tree
Showing 6 changed files with 172 additions and 102 deletions.
85 changes: 43 additions & 42 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,32 +1,60 @@
# AccurApp
This is a project kickstarter for the specific needs of Accurat.
It was originally forked from [create-react-app](https://github.com/facebookincubator/create-react-app/),
but in version 3.0.0 significant amounts of code were rewritten and simplified.
but in version 3.0.0 significant amounts of code were rewritten and simplified. Here are some added features:

## Getting started:
- ESLint config is the one configured for Accurat, `eslint-config-accurapp`, based on StandardJS with some customizations
- Babel presets are `stage-0` and `latest` with decorators support
- GLSL webpack loader, to import shaders and require shaders within shaders

## Creating a new project:
Having installed yarn (`brew install yarn`), run this command which will handle the folder scaffolding, the dependencies installation, and the git initialization with a first commit.
```sh
yarn create accurapp project-name
```

Then you just `cd project-name`, run `yarn start` and start creating awesome stuff! 🎉

## Setting up bitbucket
#### Setting up bitbucket
1. Create a new repo
1. Choose `I have an existing project` and follow the instructions

## Setting up the automatic deploy
#### Setting up the automatic deploy
1. Go into `Settings > Pipelines - Settings` and enable Bitbucket Pipelines
1. Go into `Settings > Pipelines - Environment Variables` and add the environment variables `DEPLOY_CUSTOMER`, `DEPLOY_PROJECT`, `SLACK_CHANNEL`

## Original documentation:
- [Getting Started](https://github.com/facebookincubator/create-react-app/#getting-started)
- [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)
## Usage
These are the available commands once you created a project:
- `yarn start` starts a server locally, accessible both from your browser and from another machine using your same wi-fi
- `yarn build` builds the project for production, ready to be deployed from the `build/` folder

## Features:
- ESLint config is the one configured for Accurat, `eslint-config-accurapp`, based on StandardJS with some customizations
- Babel presets are `stage-0` and `latest` with decorators support
- GLSL webpack loader, to import shaders and require shaders within shaders
#### Customizing Webpack
You can pass the custom webpack config to the `buildWebpackConfig` function in the project's `webpack.config.js`.
```js
const buildWebpackConfig = require('webpack-preset-accurapp')

module.exports = buildWebpackConfig({
target: 'node',
})
```

Or to make your life easier, you could also use [webpack-blocks](https://github.com/andywer/webpack-blocks/tree/release/1.0), it's a nice level of abstraction over the webpack configuration, you can add loaders, plugins, configuration with just one line.
```js
const buildWebpackConfig = require('webpack-preset-accurapp')
const { sass } = require('webpack-blocks')

module.exports = buildWebpackConfig([
sass(),
])
```

#### Customizing Babel
```js
// TODO do a babel-preset-accurapp if we need to customize babel
```

#### Customizing Eslint
Add your custom rules to the `.eslintrc`

## Project Scaffolding
```
Expand All @@ -50,40 +78,13 @@ Then you just `cd project-name`, run `yarn start` and start creating awesome stu
└── yarn.lock
```

## Customizing Webpack
Edit the `webpack.config.js` and add new [webpack-blocks](https://github.com/andywer/webpack-blocks), to see how to create custom blocks, add plugins, add loaders, check out their [docs](https://github.com/andywer/webpack-blocks).
```js
const buildWebpackConfig = require('webpack-preset-accurapp')
const sass = require('@webpack-blocks/sass')

module.exports = buildWebpackConfig([
sass(),
])
```

## Customizing Babel
Create a `.babelrc` and pass it to `buildWebpackConfig` in the second arguments, which is an object of overrides
```js
// .babelrc
{
"presets": ["latest"],
"plugins": ["fast-async"]
}

// webpack.config.js
const buildWebpackConfig = require('webpack-preset-accurapp')

module.exports = buildWebpackConfig([], {
babel: { babelrc: true },
})
```

## Customizing Eslint
Add your custom rules to the `.eslintrc`

## Contributing
If you make some edits and wish to test them locally you can run `yarn create-test-app` which creates a test app using the local packages.

## Original documentation:
- [Getting Started](https://github.com/facebookincubator/create-react-app/#getting-started)
- [User Guide](https://github.com/facebookincubator/create-react-app/blob/master/packages/react-scripts/template/README.md)

## TODOs
- use CommonsChunkPlugin for faster build times?
- do more beautiful console output like zeppelin does
14 changes: 7 additions & 7 deletions packages/accurapp-scripts/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,19 @@
"accurapp-scripts": "./bin/scripts.js"
},
"dependencies": {
"boxen": "^1.1.0",
"chalk": "^2.0.1",
"boxen": "^1.2.1",
"chalk": "^2.1.0",
"cross-spawn": "^5.1.0",
"detect-port": "^1.2.0",
"dotenv": "^4.0.0",
"figlet": "^1.2.0",
"fs-extra": "^3.0.1",
"fs-extra": "^4.0.1",
"latest-version": "^3.1.0",
"path": "^0.12.7",
"react-dev-utils": "^3.0.2",
"semver": "^5.3.0",
"webpack": "^2.6.1",
"webpack-dev-server": "^2.4.5"
"react-dev-utils": "^4.0.1",
"semver": "^5.4.1",
"webpack": "^3.5.6",
"webpack-dev-server": "^2.7.1"
},
"devDependencies": {}
}
2 changes: 1 addition & 1 deletion packages/accurapp-scripts/scripts/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ const chalk = require('chalk')
const path = require('path')
const fs = require('fs-extra')
const { measureFileSizesBeforeBuild, printFileSizesAfterBuild } = require('react-dev-utils/FileSizeReporter')
const { log, createWebpackCompiler, readWebpackConfig, coloredBanner } = require('./_utils')
const { log, createWebpackCompiler, readWebpackConfig, coloredBanner } = require('./_utils')

const appDir = process.cwd()
const config = readWebpackConfig()
Expand Down
94 changes: 67 additions & 27 deletions packages/webpack-preset-accurapp/customBlocks.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,42 @@
const fileNameTemplate = '[name].[hash:8].[ext]'

/**
* You will be able to import starting from the src folder so you don't have to ../../../
* Images smaller than 10kb are loaded as a base64 encoded url instead of file url
*/
function resolveSrc() {
return () => ({
resolve: {
modules: ['node_modules', 'src'],
function imageLoader() {
return (context, { addLoader }) => addLoader({
test: /\.(gif|ico|jpg|jpeg|png|webp)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: fileNameTemplate,
},
})
}

/**
* Videos smaller than 10kb are loaded as a base64 encoded url instead of file url
*/
function videoLoader() {
return (context, { addLoader }) => addLoader({
test: /\.(mp4|webm)$/,
loader: 'url-loader',
options: {
limit: 10000,
name: fileNameTemplate,
},
})
}

/**
* Fonts are loaded as file urls
*/
function fontLoader() {
return (context, { addLoader }) => addLoader({
test: /\.(eot|ttf|woff|woff2)(\?.*)?$/,
loader: 'file-loader',
options: {
name: fileNameTemplate,
},
})
}
Expand All @@ -14,31 +46,32 @@ function resolveSrc() {
* allowing you to install GLSL modules from npm and use them in your shaders.
*/
function glslifyLoader() {
return () => ({
module: {
loaders: [ // TODO change this in rules when webpack-blocks 1.0 is out
{
test: /\.(glsl|frag|vert)$/,
loaders: ['raw-loader', 'glslify-loader'],
},
],
},
return (context, { addLoader }) => addLoader({
test: /\.(glsl|frag|vert)$/,
use: ['raw-loader', 'glslify-loader'],
})
}

/**
* Run ESLint on every required file.
*/
function eslintLoader() {
return () => ({
module: {
loaders: [{
test: /\.(js|jsx)$/,
enforce: 'pre', // It's important to do this before Babel processes the JS.
exclude: [/node_modules/],
loader: 'eslint-loader',
options: { useEslintrc: true },
}],
return (context, { addLoader }) => addLoader({
test: /\.(js|jsx)$/,
enforce: 'pre', // It's important to do this before Babel processes the JS.
exclude: /node_modules/,
loader: 'eslint-loader',
options: { useEslintrc: true },
})
}

/**
* You will be able to import starting from the src folder so you don't have to ../../../
*/
function resolveSrc() {
return (context, { merge }) => merge({
resolve: {
modules: ['node_modules', 'src'],
},
})
}
Expand All @@ -47,21 +80,28 @@ function eslintLoader() {
* Add entryPoint at beginning of 'entry' array
*/
function prependEntry(entry) {
const blockFunction = (context, config) => {
const blockFunction = (context, util) => {
if (!context.entriesToPrepend) context.entriesToPrepend = []
context.entriesToPrepend.unshift(entry)
return config => config
}
return Object.assign(blockFunction, {
post: prependEntryPostHook,
})
}
function prependEntryPostHook(context, config) {
config.entry.main.unshift(...context.entriesToPrepend)
function prependEntryPostHook(context, util) {
return (config) => {
config.entry.main.unshift(...context.entriesToPrepend)
return config
}
}

module.exports = {
resolveSrc,
imageLoader,
videoLoader,
fontLoader,
glslifyLoader,
eslintLoader,
resolveSrc,
prependEntry,
}
58 changes: 42 additions & 16 deletions packages/webpack-preset-accurapp/index.js
Original file line number Diff line number Diff line change
@@ -1,24 +1,42 @@
const { addPlugins, createConfig, customConfig, env, entryPoint, setOutput, sourceMaps, webpack } = require('@webpack-blocks/webpack2')
const babelLoader = require('@webpack-blocks/babel6')
const postcss = require('@webpack-blocks/postcss')
const webpack = require('webpack')
const {
createConfig,
addPlugins,
customConfig,
entryPoint,
setOutput,
env,
performance,
sourceMaps,
babel,
postcss,
} = require('webpack-blocks')
const { css } = require('@webpack-blocks/assets')
const autoprefixer = require('autoprefixer')
const path = require('path')

const HtmlWebpackPlugin = require('html-webpack-plugin')
const InterpolateHtmlPlugin = require('react-dev-utils/InterpolateHtmlPlugin')
const CaseSensitivePathsPlugin = require('case-sensitive-paths-webpack-plugin')
const WatchMissingNodeModulesPlugin = require('react-dev-utils/WatchMissingNodeModulesPlugin')
const NpmInstallPlugin = require('npm-install-webpack-plugin')
const MinifyPlugin = require('babel-minify-webpack-plugin')

const { resolveSrc, glslifyLoader, eslintLoader, prependEntry } = require('./customBlocks')
const {
imageLoader,
videoLoader,
fontLoader,
glslifyLoader,
eslintLoader,
resolveSrc,
prependEntry,
} = require('./customBlocks')

// TODO move browsers in package.json when they will be supported https://github.com/babel/babel-preset-env/issues/149
const browsers = process.env.NODE_ENV === 'development' ? ['last 1 Chrome version'] : ['last 2 versions', 'ie 10']
const babelrc = require('./babelrc')(browsers)

// TODO understand how to customize file-loader in webpack-blocks to set the output asset name line create-react-app does instead of only hash: '[name].[hash:8].[ext]' https://github.com/andywer/webpack-blocks/issues/145

function accuPreset(blocks = [], overrides = {}) {
function accuPreset(config = []) {
return createConfig([
entryPoint([
// Include all polyfills we can, to prevent cross-browser bugs.
Expand All @@ -31,9 +49,16 @@ function accuPreset(blocks = [], overrides = {}) {
filename: 'app.js',
publicPath: '/',
}),
resolveSrc(),

// Loaders
css(),
babel(babelrc),
fontLoader(),
imageLoader(),
videoLoader(),
glslifyLoader(),
babelLoader(overrides.babel || babelrc),

resolveSrc(),

addPlugins([
// Makes some environment variables available to the JS code
Expand All @@ -53,6 +78,9 @@ function accuPreset(blocks = [], overrides = {}) {
}),
// Check case of paths, so case-sensitive filesystems won't complain:
new CaseSensitivePathsPlugin(),
// Concatenate the scope of all module in a single closure,
// so the compiled code is a bit smaller and gets executed a bit faster
new webpack.optimize.ModuleConcatenationPlugin(),
]),

//
Expand All @@ -73,15 +101,13 @@ function accuPreset(blocks = [], overrides = {}) {
new webpack.HotModuleReplacementPlugin(),
// Automatic rediscover of packages after `npm install`
new WatchMissingNodeModulesPlugin('node_modules'),
// Automatically install dependencies when you type `import ...` in your editor
new NpmInstallPlugin(),
]),
// Faster 'cheap-module-eval-source-map' instead of the standard 'cheap-module-source-map'
sourceMaps('cheap-module-eval-source-map'),
customConfig({
// Turn off performance hints during development
performance: {
hints: false,
},
}),
// Turn off performance hints during development
performance({ hints: false }),
]),

//
Expand Down Expand Up @@ -124,7 +150,7 @@ function accuPreset(blocks = [], overrides = {}) {
]),
]),

...blocks,
...(Array.isArray(config) ? config : [customConfig(config)]),
])
}

Expand Down
Loading

0 comments on commit 7b80b3f

Please sign in to comment.