Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Various webpack updates #31

Merged
merged 11 commits into from
Sep 14, 2017
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