example-app ├── .gitignore ├── .editorconfig ├── .eslintrc.json ├── package.json └── README.md
.idea
/*.env
node_modules
public/
npm-debug.log
root = true
[*]
charset = utf-8
end_of_line = lf
indent_size = 4
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.json]
indent_style = space
indent_size = 2
[*.yml]
indent_style = space
indent_size = 2
{
"parserOptions": {
"ecmaVersion": 6
},
"env": {
"browser": true,
"mocha": true,
"node": true
},
"extends": "xo",
"rules": {
"indent": [2, 4, {"SwitchCase": 1}],
"max-len": [2, 100],
"max-params": [2, 3]
}
}
{
"name": "example-app",
"version": "1.0.0",
"main": "dist",
"license": "MIT",
"scripts": { ... },
"dependencies": { ... },
"devDependencies": { ... },
"engines": {
"node": "4.4.0"
}
}
example-app ├── .gitignore ├── .editorconfig ├── package.json ├── README.md ├── client //Клиенска часть ├── server //Серверная часть (express api db) └── public //Папка которые отдаются браузеру
example-app ├── .gitignore ├── .editorconfig ├── package.json ├── README.md ├── client └─┬ server ├── app.js // Приложения └── routes.js // Роутинги приложения
example-app ├── .gitignore ├── .editorconfig ├── package.json ├── README.md └─┬ server ├── middleware ├── utils ├── models ├── views ├── controllers ├── app.js └── routes.js
example-app
└─┬ client
└─┬ components
├─┬ form
│ ├── form.css
│ └── form.jsx
├─┬ item
│ ├── item.css
│ └── item.jsx
└─┬ list
├── list.css
└── list.jsx
Меньше вероятность конфликтов
Легкое переиспользование кода
example-app
└─┬ client
└─┬ components
├─┬ form
│ ├── form.css
│ └── form.jsx
├─┬ item
│ ├── item.css
│ └── item.jsx
└─┬ list
├── list.css
└── list.jsx
public ├── form.css ├── item.css ├── list.css ├── form.js ├── item.js └── list.js
<head>
<link href="/form.css" rel="stylesheet">
<link href="/item.css" rel="stylesheet">
<link href="/list.css" rel="stylesheet">
<script src="/form.js"></script>
<script src="/item.js"></script>
<script src="/list.js"></script>
</head>
Работает
Медленно загружается
Много запросов за ресурсами
Много копирований при сборке
Ограничение на количество подключаемых ресурсов (в IE)
define(['my-module', 'my-module2'],
function (MyModule, MyModule2) {
return { ... };
});
define(function (require, module, exports) {
var MyModule = require('my-module');
var MyModule2 = require('my-module2');
module.exports = { ... };
});
var MyModule = require('my-module');
var MyModule2 = require('my-module2');
module.exports = { ... };
import MyModule from 'my-module';
import MyModule2 from 'my-module2';
export { ... };
export default class MyModule {
constructor(id, name) {
this.id = id;
this.name = name;
}
};
import MyModule from 'my-module';
import MyModule {metod1, metod2} from 'my-module';
import * as MyModule from 'my-module';
import {metod1 as alias1} from 'my-module2';
npm install --save-dev webpack
test-webpack ├── my-module.js ├── test.js └── webpack.config.js
my-module.js
export function method1() {
console.log('method1 my module');
}
export function method2() {
console.log('method2 my module');
}
export default function () {
console.log('init my module');
}
test.js
import MyModule ,{method1,method2} from './my-module'
MyModule();
method1();
method2();
webpack.config.js
module.exports = {
entry: './test.js',
output: {
filename: 'test.bundle.js',
}
}
webpack
test-webpack ├── my-module.js ├── test.js ├── todo.bundle.js └── webpack.config.js
todo.bundle.js
/************************************************************************/
/******/ ([
/* 0 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
/* harmony export (immutable) */ __webpack_exports__["b"] = method1;
/* harmony export (immutable) */ __webpack_exports__["c"] = method2;
function method1() {
console.log('method1 my module');
}
function method2() {
console.log('method2 my module');
}
/* harmony default export */ __webpack_exports__["a"] = function () {
console.log('init my module');
};
/***/ }),
my-module.js
export function method1() {
console.log('method1 my module');
}
export function method2() {
console.log('method2 my module');
}
export default function () {
console.log('init my module');
}
todo.bundle.js
/* 1 */
/***/ (function(module, __webpack_exports__, __webpack_require__) {
"use strict";
Object.defineProperty(__webpack_exports__, "__esModule", { value: true });
/* harmony import */
var __WEBPACK_IMPORTED_MODULE_0_my_module__ = __webpack_require__(0);
__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0_my_module__["a" /* default */])();
__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0_my_module__["b" /* method1 */])();
__webpack_require__.i(__WEBPACK_IMPORTED_MODULE_0_my_module__["c" /* method2 */])();
/***/ })
/******/ ]);
test.js
import MyModule ,{method1,method2} from './my-module'
MyModule();
method1();
method2();
example-app └── webpack.config.js
module.exports = {
context: __dirname + "/client",
entry: "todo.js",
output: {
path: __dirname + "/public",
filename: "todoPage.bundle.js"
}
}
example-app └─┬ client └── todo.jsx
import ReactDOM from 'react-dom';
import TodoPage from './pages/todoPage';
import React from 'react';
export default function (data) {
const mountNode = document.getElementById("app");
ReactDOM.render( , mountNode);
}
npm i --save-dev babel-loader babel-core
example-app └── webpack.config.js
module.exports = {
rules: [
{
test: /(\.jsx|\.js)$/, // Для филтрации по расширению
include: __dirname + "/client", // Для филтрации по папке
exclude: /node_modules/, // Не учитывать
loader: "babel-loader"
}
]
}
example-app └── .babelrc
{
"presets": ["es2015", "stage-0", "react"]
}
example-app └── package.json
"scripts": {
"build": "webpack"
}
npm run build
example-app └─┬ public ├── form.css ├── item.css ├── list.css └── todo.bundle.js
<head>
<link href="/form.css" rel="stylesheet">
<link href="/item.css" rel="stylesheet">
<link href="/list.css" rel="stylesheet">
<script src="/todo.bundle.js"></script>
</head>
example-app
└─┬ client
└─┬ components
└─┬ form
├── form.css
└── form.jsx
import './form.css';
npm run build
You may need an appropriate
loader to handle this file type.
npm i style-loader --save-dev
npm i css-loader --save-dev
example-app └── webpack.config.js
module.exports = {
rules: [
...
{
test: /\.css$/,
use: ['style-loader','css-loader']
}
]
}
<head>
<style type="text/css">
body {
font-family: Arial, sans-serif;
}
</style>
<style type="text/css">
header {
border-bottom: 1px solid #ccc;
}
</style>
</head>
example-app └── webpack.config.js
import ExtractTextPlugin from 'extract-text-webpack-plugin';
module.exports = {
...
plugins: [
new ExtractTextPlugin("bundle.css")
]
}
example-app └── webpack.config.js
module.exports = {
rules: [
{
test: /\.css$/,
use: ExtractTextPlugin
.extract('style-loader', 'css-loader')
}
]
}
example-app └─┬ public ├── bundle.css └── todo.bundle.js
<head>
<link href="/bundle.css" rel="stylesheet">
<script src="/todo.bundle.js"></script>
</head>
example-app └─┬ components └─┬ list ├── list.css ├── background.png └── list.jsx
example-app └─┬ components └─┬ list └── list.css
.list {
background: url(background.png)
}
npm install file-loader --save-dev
example-app └── webpack.config.js
module.exports = {
rules: [
{
test: /(\.png|\.jpg)$/,
use: "file-loader"
}
]
}
example-app └─┬ public ├── bundle.css ├── todo.bundle.js └── 9d86ab26bc61bc94bf09d352edff07a1.png
.list {
background: url("./9d86ab2...7a1.png")
}
расстановка браузерных префиксов
оптимизация и минификация
отладка
цветовые фунции
...
Набор js плагинов для трансформации стилй
npm i --save-dev postcss-loader
example-app └── postcss.config.js
module.exports = {
plugins: [
require('postcss-cssnext')({ /* ...options */ }), // plugins[1]
require('autoprefixer')({ /* ...options */ }) // plugins[2]
require('cssnano')({ /* ...options */ }) // plugins[3]
]
}
npm i --save-dev postcss-cssnext
:root {
--fontSize: 1rem;
}
.list {
& .item {
font-size: var(--fontSize);
line-height: calc(var(--fontSize) * 1.5);
}
}
.list .item {
font-size: 16px;
font-size: 1rem;
line-height: 24px;
line-height: 1.5rem;
}
npm i --save-dev autoprefixer
.list {
display: flex;
}
.list {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
example-app └─┬ components └─┬ list └── list.css
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
example-app └─┬ components └─┬ list └── list.css
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
example-app └─┬ components └─┬ list └── list.css
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
example-app └─┬ components └─┬ list └── list.css
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
example-app └─┬ components └─┬ list └── list.css
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
npm i --save-dev cssnano
.list {
div { margin: 0 0 0 0; }
div {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
}
}
.list div{margin:0;display:-webkit-box;display:-webkit-flex;display:-ms-flexbox;display:flex}
example-app └── webpack.config.js
var webpack = require('webpack');
module.exports = {
...
plugins: [
...
new webpack.optimize.UglifyJsPlugin()
]
}
!function(o){function n(e){if(t[e])return t[e]. ....
example-app └── webpack.config.js
module.exports = {
...
devtool: 'source-map'
}
example-app └─┬ public ├── todo.bundle.js └── todo.bundle.js.map
example-app └─┬ public └── todo.bundle.js
...
//# sourceMappingURL=todo.bundle.js.map
└── todo.bundle.js.map
{"version":3,"sources":["List","map","item"],"mappings":";;AAAA;AACA;;AAEA;AACA;;AAEA;AACA;AACA;;AAEA;
example-app └── webpack.config.js
module.exports = {
...
entry: {
mainPage: './mainPage.js',
innerPage: './innerPage.js'
},
output: {
filename: "[name].bundle.js"
}
plugins: [
new ExtractTextPlugin("[name].css")
]
}