├── 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 |
17 | - {{$index}}--{{el}}
18 |
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 |
17 | - {{$index}}--{{el}}
18 |
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 | [](https://travis-ci.org/sayll/avalon-webpack-start) [](https://coveralls.io/github/sayll/avalon-webpack-start) [](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