├── app ├── app.js └── views │ ├── test │ ├── index.css │ ├── index.js │ └── index.html │ └── index │ ├── index.css │ ├── bg.jpg │ ├── index.js │ └── index.html ├── .eslintignore ├── .editorconfig ├── .travis.yml ├── .babelrc ├── .codeclimate.yml ├── .postcssrc.js ├── .gitignore ├── internals ├── webpack │ ├── webpack.dll.js │ ├── webpack.dev.js │ ├── server.js │ ├── utils.js │ ├── webpack.prod.js │ └── webpack.common.js └── index.js ├── LICENSE ├── .eslintrc.yml ├── package.json ├── README.md └── static └── lib └── polyfills.js /app/app.js: -------------------------------------------------------------------------------- 1 | console.log('app.js:引入成功') 2 | -------------------------------------------------------------------------------- /app/views/test/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | color: #abcdef; 3 | } 4 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | ## 项目 2 | *.pcss 3 | internals 4 | 5 | ## Node.js 6 | node_modules 7 | -------------------------------------------------------------------------------- /app/views/index/index.css: -------------------------------------------------------------------------------- 1 | body { 2 | background: url("./bg.jpg") no-repeat; 3 | } 4 | -------------------------------------------------------------------------------- /app/views/index/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/sayll/avalon-webpack-start/HEAD/app/views/index/bg.jpg -------------------------------------------------------------------------------- /app/views/index/index.js: -------------------------------------------------------------------------------- 1 | console.log('index.js:引入成功') 2 | 3 | avalon.define({ 4 | $id: 'app', 5 | name: 'Avalon', 6 | array: [1, 2, 3, 4] 7 | }) 8 | -------------------------------------------------------------------------------- /app/views/test/index.js: -------------------------------------------------------------------------------- 1 | console.log('index.js:引入成功') 2 | 3 | avalon.define({ 4 | $id: 'app', 5 | name: 'Avalon', 6 | array: [1, 2, 3, 4] 7 | }) 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | charset = utf-8 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | insert_final_newline = true 9 | trim_trailing_whitespace = true 10 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - '7' 4 | before_script: 5 | - export DISPLAY=:99.0 6 | - sh -e /etc/init.d/xvfb start 7 | install: 8 | - npm install 9 | - npm run installKarma 10 | - npm install coveralls 11 | script: 12 | - npm run test 13 | after_script: 14 | - npm run test:coveralls -------------------------------------------------------------------------------- /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "presets": [ 3 | [ 4 | "es2015", 5 | { 6 | "modules": false 7 | } 8 | ], 9 | "stage-0" 10 | ], 11 | "plugins": [ 12 | "lodash", 13 | "transform-runtime" 14 | ], 15 | "env": { 16 | "development": { 17 | "plugins": [] 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /.codeclimate.yml: -------------------------------------------------------------------------------- 1 | engines: 2 | csslint: 3 | enabled: true 4 | duplication: 5 | enabled: false 6 | config: 7 | languages: 8 | - javascript 9 | eslint: 10 | enabled: true 11 | checks: 12 | linebreak-style: 13 | enabled: false 14 | global-require: 15 | enabled: false 16 | fixme: 17 | enabled: true 18 | ratings: 19 | paths: 20 | - app/**/* 21 | exclude_paths: 22 | - app/static/tools/**/* 23 | - app/source/font/**/* 24 | - app/source/css/library/**/* 25 | - app/source/css/parts/**/* -------------------------------------------------------------------------------- /.postcssrc.js: -------------------------------------------------------------------------------- 1 | // https://github.com/michael-ciniawsky/postcss-load-config 2 | 3 | module.exports = ctx => ({ 4 | parser: false, 5 | map: ctx.env === 'development' ? 'inline' : false, 6 | plugins: { 7 | cssnano: { 8 | safe: true // 避免 cssnano 重新计算 z-index 9 | }, 10 | 'postcss-import': {}, 11 | 'postcss-url': {}, 12 | 'postcss-cssnext': {} 13 | /*'postcss-pxtorem': { 14 | rootValue: 18, 15 | // px单位大写将忽略转化rem 16 | propList: ['!*'], 17 | selectorBlackList: [] // 忽略的选择器 18 | },*/ 19 | } 20 | }) 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## 项目 2 | .idea/ 3 | build/ 4 | dist/ 5 | 6 | ## Node.js 7 | node_modules 8 | jspm_packages 9 | bower_components 10 | 11 | # 编辑器 12 | 13 | ## Sublime 14 | *.sublime-workspace 15 | 16 | ## Webstorm 17 | .idea/workspace.xml 18 | .idea/tasks.xml 19 | .idea/dataSources* 20 | .idea/libraries/ 21 | *.iws 22 | 23 | ## Visual Studio 24 | .vs 25 | **/[Bb]in/[Dd]ebug/ 26 | **/[Bb]in/[Rr]elease/ 27 | [Oo]bj/ 28 | *.sln.* 29 | *.vshost.* 30 | *.suo 31 | *.user 32 | _ReSharper* 33 | *.ReSharper 34 | .ntvs_analysis.dat 35 | **/[Bb]in/Microsoft.NodejsTools.WebRole.dll 36 | 37 | # 操作系统 38 | 39 | ## 临时文件 40 | *.tmp 41 | *.log 42 | *~ 43 | .cache-loader 44 | ._* 45 | 46 | ## Windows 47 | *.lnk 48 | $RECYCLE.BIN 49 | Desktop.ini 50 | ehthumbs.db 51 | Thumbs.db 52 | 53 | ## OSX 54 | .DS_Store 55 | -------------------------------------------------------------------------------- /internals/webpack/webpack.dll.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | 3 | const utils = require('./utils') 4 | 5 | // 没有依赖,跳出执行 6 | !utils.vendors.length && process.exit(0) 7 | 8 | module.exports = { 9 | devtool: 'eval', 10 | entry: { 11 | vendors: utils.vendors 12 | }, 13 | output: { 14 | path: utils.resolve(utils.path.dll), 15 | filename: '[name].js', 16 | library: '[name]' 17 | }, 18 | plugins: [ 19 | new webpack.DllPlugin({ 20 | path: utils.resolve(utils.path.dll, 'vendors.json'), 21 | name: '[name]', 22 | context: '/' 23 | }), 24 | new webpack.DefinePlugin({ 25 | 'NICE_FEATURE': JSON.stringify(!utils.isDev), 26 | 'process.env': { 27 | NODE_ENV: JSON.stringify(process.env.NODE_ENV) 28 | } 29 | }), 30 | new webpack.optimize.ModuleConcatenationPlugin() // 提升作用域 31 | ], 32 | performance: { 33 | hints: false 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /app/views/index/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Title 11 | 12 | 13 |
14 | 15 |

Hello,{{@name}}!

16 | 19 |
20 | 21 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /app/views/test/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | Title 11 | 12 | 13 |
14 | 15 |

Hello,{{@name}}!

16 | 19 |
20 | 21 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /internals/index.js: -------------------------------------------------------------------------------- 1 | const path = require('path') 2 | 3 | const filesPath = { 4 | app: 'app', // 资源根目录 5 | dist: 'dist', // 打包文件 6 | dll: 'dist/vendors', // dll打包文件 7 | utils: 'app/utils', // 资源目录 8 | static: 'static', // 静态文件目录 9 | assets: 'app/assets', // 资源目录 10 | views: 'app/views', // 视图 11 | components: 'app/components' // 组件目录 12 | } 13 | 14 | module.exports = { 15 | path: filesPath, 16 | vendors: [ 17 | 'avalon2' 18 | ], 19 | dev: { 20 | eslint: false, 21 | port: 3001, 22 | assetsPath: 'assets', 23 | assetsPublicPath: '/', 24 | sourceMap: true 25 | }, 26 | build: { 27 | eslint: false, 28 | // 服务根目录 29 | assetsRoot: path.resolve(process.cwd(), filesPath.dist), 30 | // 指向静态资源 31 | assetsPath: 'assets', 32 | assetsPublicPath: './', 33 | // 是否生成用于生产构建的源映射 34 | sourceMap: false, 35 | // Gzip 默认关闭如需开启请安装下列依赖 36 | // npm install --save-dev compression-webpack-plugin 37 | productionGzip: false, 38 | productionGzipExtensions: ['js', 'css'] 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Wait 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /.eslintrc.yml: -------------------------------------------------------------------------------- 1 | env: 2 | es6: true 3 | node: true 4 | mocha: true 5 | browser: true 6 | 7 | # parser: babel-eslint # Es5 解析器 8 | 9 | extends: 10 | - airbnb 11 | #- eslint:recommended 12 | 13 | parserOptions: 14 | allowImportExportEverywhere: true 15 | ecmaVersion: 8 16 | ecmaFeatures: 17 | jsx: true 18 | globalReturn: true 19 | impliedStrict: true 20 | experimentalObjectRestSpread: true 21 | sourceType: module 22 | 23 | #plugins: 24 | # - react 25 | 26 | rules: 27 | arrow-parens: 28 | - warn 29 | - as-needed 30 | brace-style: off 31 | comma-dangle: 32 | - error 33 | - only-multiline 34 | consistent-return: off # 总返回value 35 | eol-last: off 36 | import/no-unresolved: off 37 | global-require: off 38 | 39 | # 自定义模块警告 40 | linebreak-style: off 41 | no-bitwise: off # 禁用位运算 42 | no-console: off 43 | no-plusplus: off 44 | no-underscore-dangle: off 45 | no-unused-vars: warn 46 | no-trailing-spaces: off # 禁止多余空格 47 | no-unused-expressions: off # a && b 48 | max-len: off # 禁止单行超出100字节 49 | quotes: 50 | - error 51 | - single 52 | spaced-comment: off 53 | semi: off 54 | 55 | globals: 56 | module: false 57 | window: false 58 | document: false 59 | avalon: true 60 | localStorage: true 61 | -------------------------------------------------------------------------------- /internals/webpack/webpack.dev.js: -------------------------------------------------------------------------------- 1 | const webpack = require('webpack') 2 | const webpackMerge = require('webpack-merge') 3 | const IncludeAssetsPlugin = require('html-webpack-include-assets-plugin') 4 | 5 | const utils = require('./utils') 6 | const common = require('./webpack.common') 7 | 8 | Object.keys(common.entry).forEach(name => { 9 | common.entry[name].unshift( 10 | 'webpack-hot-middleware/client?noInfo=true&reload=true' 11 | //'eventsource-polyfill' // 热替换兼容低版IE 12 | ) 13 | }) 14 | 15 | module.exports = webpackMerge(common, { 16 | devtool: 'cheap-module-eval-source-map', 17 | plugins: [ 18 | // 热更新 19 | new webpack.HotModuleReplacementPlugin() 20 | ], 21 | module: { 22 | rules: [ 23 | { 24 | test: /\.css|pcss$/, 25 | include: [utils.resolve(utils.path.app)], 26 | use: [ 27 | 'style-loader', 28 | 'css-loader', 29 | 'postcss-loader' 30 | ] 31 | } 32 | ] 33 | } 34 | }) 35 | 36 | utils.vendors.length && ( 37 | module.exports.plugins.push( 38 | new IncludeAssetsPlugin({ 39 | assets: [`${utils.path.dll.replace(`${utils.path.dist}/`, '')}/vendors.js`], 40 | append: false, 41 | hash: true 42 | }), 43 | new webpack.DllReferencePlugin({ 44 | context: '/', 45 | manifest: require(utils.resolve(utils.path.dll, `vendors.json`)) 46 | }) 47 | ) 48 | ) 49 | -------------------------------------------------------------------------------- /internals/webpack/server.js: -------------------------------------------------------------------------------- 1 | const express = require('express') 2 | const webpack = require('webpack') 3 | const webpackDevMiddleware = require('webpack-dev-middleware') 4 | const webpackHotMiddleware = require('webpack-hot-middleware') 5 | const DashboardPlugin = require('webpack-dashboard/plugin') 6 | const dashboard = require('webpack-dashboard') 7 | 8 | // 配置文件 9 | const config = require('./webpack.dev.js') 10 | const utils = require('./utils') 11 | 12 | const app = express() 13 | const compiler = webpack(config) 14 | // 美化控制台 15 | compiler.apply(new DashboardPlugin(new dashboard({ 16 | port: utils.dev.port, 17 | minimal: true, 18 | title: 'Sayll', 19 | color: '#2ba1cb' 20 | }).setData)) 21 | 22 | // configuration file as a base. 23 | app.use(webpackDevMiddleware(compiler, { 24 | publicPath: config.output.publicPath, 25 | quiet: true, 26 | stats: { colors: true }, 27 | noInfo: false, 28 | hot: true 29 | })) 30 | 31 | app.use(webpackHotMiddleware(compiler, { 32 | log: (msg) => { 33 | //console.log(msg) 34 | } 35 | })) 36 | 37 | // 404 pages 38 | app.use(require('connect-history-api-fallback')()) 39 | // serve pure static assets 40 | app.use('/static', express.static(utils.resolve(utils.path.static))) 41 | app.use('/', express.static(utils.resolve(utils.path.dist))) 42 | 43 | // Serve the files on port 3000. 44 | app.listen(utils.dev.port, function () { 45 | console.log(`App listening on port ${utils.dev.port}!\n`) 46 | }) 47 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "avalon-webpack-start", 3 | "main": "mian.js", 4 | "scripts": { 5 | "start": "bnr dll && bnr dev", 6 | "dev": "bnr dev", 7 | "dll": "bnr dll", 8 | "build": "bnr build", 9 | "bundle": "bnr build:bundle", 10 | "deploy": "bnr deploy" 11 | }, 12 | "betterScripts": { 13 | "dev": { 14 | "command": "node ./internals/webpack/server.js", 15 | "env": { 16 | "$Server": "true", 17 | "NODE_ENV": "development" 18 | } 19 | }, 20 | "dll": { 21 | "command": "webpack --progress --config ./internals/webpack/webpack.dll.js", 22 | "env": { 23 | "NODE_ENV": "production" 24 | } 25 | }, 26 | "build": { 27 | "command": "webpack --progress --config ./internals/webpack/webpack.prod.js", 28 | "env": { 29 | "NODE_ENV": "development" 30 | } 31 | }, 32 | "build:bundle": { 33 | "command": "webpack --progress --config ./internals/webpack/webpack.prod.js", 34 | "env": { 35 | "NODE_ENV": "production", 36 | "$Analyzer": "true" 37 | } 38 | }, 39 | "deploy": { 40 | "command": "webpack --progress --config ./internals/webpack/webpack.prod.js", 41 | "env": { 42 | "NODE_ENV": "production" 43 | } 44 | } 45 | }, 46 | "license": "MIT", 47 | "devDependencies": { 48 | "babel-core": "^6.26.0", 49 | "babel-loader": "^7.1.2", 50 | "babel-plugin-lodash": "^3.2.11", 51 | "babel-plugin-transform-runtime": "^6.23.0", 52 | "babel-preset-es2015": "^6.24.1", 53 | "babel-preset-stage-0": "^6.24.1", 54 | "better-npm-run": "^0.1.0", 55 | "bundle-loader": "^0.5.5", 56 | "cache-loader": "^1.0.3", 57 | "clean-webpack-plugin": "^0.1.16", 58 | "connect-history-api-fallback": "^1.3.0", 59 | "copy-webpack-plugin": "^4.0.1", 60 | "css-loader": "^0.28.7", 61 | "cssnano": "^3.10.0", 62 | "eslint": "^4.5.0", 63 | "eslint-config-airbnb": "^15.1.0", 64 | "eslint-friendly-formatter": "^3.0.0", 65 | "eslint-loader": "^1.9.0", 66 | "eslint-plugin-import": "^2.7.0", 67 | "eslint-plugin-jsx-a11y": "^5.1.1", 68 | "eslint-plugin-react": "^7.3.0", 69 | "express": "^4.15.4", 70 | "extract-text-webpack-plugin": "^3.0.0", 71 | "file-loader": "^0.11.2", 72 | "glob": "^7.1.2", 73 | "happypack": "^4.0.0", 74 | "html-webpack-include-assets-plugin": "^0.0.7", 75 | "html-webpack-plugin": "^2.30.1", 76 | "postcss-cssnext": "^3.0.2", 77 | "postcss-import": "^10.0.0", 78 | "postcss-loader": "^2.0.6", 79 | "postcss-modules": "^0.8.0", 80 | "postcss-url": "^7.1.2", 81 | "style-loader": "^0.18.2", 82 | "uglifyjs-webpack-plugin": "^0.4.6", 83 | "url-loader": "^0.5.9", 84 | "webpack": "^3.5.6", 85 | "webpack-bundle-analyzer": "^2.9.0", 86 | "webpack-dashboard": "^0.4.0", 87 | "webpack-dev-middleware": "^1.12.0", 88 | "webpack-hot-middleware": "^2.19.1", 89 | "webpack-merge": "^4.1.0" 90 | }, 91 | "dependencies": { 92 | "avalon2": "^2.2.9" 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # avalon-webpack-start 2 | [![Coverage Status](https://travis-ci.org/sayll/avalon-webpack-start.svg?branch=master)](https://travis-ci.org/sayll/avalon-webpack-start)  [![Coverage Status](https://coveralls.io/repos/github/sayll/avalon-webpack-start/badge.svg)](https://coveralls.io/github/sayll/avalon-webpack-start) [![Coverage Status](https://codeclimate.com/github/sayll/avalon-webpack-start/badges/gpa.svg)](https://codeclimate.com/github/sayll/avalon-webpack-start) 3 | 4 | Vue 用户请转至:[vue-start](https://github.com/sayll/vue-start) 5 | 6 | React 用户请转至:[react-webpack-start](https://github.com/sayll/react-webpack-start) 7 | 8 | 低版本IE 用户请转至:[ie-webpack-start](https://github.com/sayll/ie-webpack-start) 9 | 10 | 旧版脚手架[v2.1.0](https://github.com/sayll/avalon-webpack-start/tree/v2.1.0) 11 | 12 | ## 介绍 13 | 本版本删减了许多模块及功能,让脚手架更轻型,更易扩展,自定义。 14 | 本项目使用[`avalon2`](https://github.com/RubyLouvre/avalon)作为演示框架,演示如何进入开发。 15 | 16 | ### 关于本项目功能 17 | 1. 服务端使用Express。需要注意的是,只有一个目的那就是提供了`webpack-dev-middleware` 和 `webpack-hot-middleware`(代码热替换)。使用自定义的Express程序替换[webpack-dev-server](https://github.com/webpack/webpack-dev-server),让它更容易实现universal 渲染和为了不使这个包过于庞大。 18 | 2. 针对不同的loader采用了多线程编译,极大的加快了编译速度。 19 | 3. 使用webpack.DllReferencePlugin提取固定资源,加快编译与打包速度。 20 | 4. 启动tree-shaking 21 | 5. 启动webpack3版本:作用域提升功能 22 | 6. Babel配有transform-runtime让代码更优化。 23 | 7. 支持单页应用和多页应用的混合开发 24 | 8. 自动引入页面的CSS和JS文件。无需手动设置URL 25 | 9. 更改文件,防缓存的hash规则 26 | 10. css的模块化,默认使用postcss + postcss-cssnext,内置处理浏览器前缀。[查看更多](http://cssnext.io/) 27 | 11. 全面支持ES6的最新特性,打包转义为ES5为低版本浏览器提供支持 28 | 12. 快速编译,热更新,自动刷新 29 | 30 | ## 程序目录 31 | 32 | ``` 33 | ├── dist # 打包资源 34 | ├── internals # 项目配置文件 35 | │   ├── webpack # webpack配置文件夹 36 | │ └── index.js # 公共配置文件 37 | ├── static # 静态资源,直接绕过打包 38 | ├── app # 程序源文件 39 | └── .cache-loader            # 启动服务后的缓存文件,用于下次快速启动服务 40 | ``` 41 | 42 | ## 项目启动 43 | 44 | ### 环境配置 45 | * 为了把保证项目正常运行,请自行更新相关环境。 46 | 1. 安装[node.js](https://nodejs.org/) 47 | 2. 安装[git](https://git-scm.com/) 48 | 49 | ### 依赖配置 50 | 1. 首先clone项目 51 | ```bash 52 | $ git clone https://github.com/sayll/avalon-webpack-start.git 53 | $ cd avalon-webpack-start 54 | ``` 55 | 56 | 2. 下载依赖 57 | * 请确保你的环境配置完成,然后就可以开始以下步骤 58 | ```bash 59 | $ npm install # Install project dependencies 60 | $ npm start # Compile and launch 61 | ``` 62 | 如果一切顺利,就能正常打开端口:[http://127.0.0.1:3001/](http://127.0.0.1:3001/) 63 | 64 | ## 命令说明 65 | 66 | 开发过程中,你用得最多的会是`npm run dev`,但是这里还有很多其它的处理: 67 | 68 | |`npm run