Гладкий Максим Валерьевич / github:MaksHladki
Программная платформа, основанная на движке V8 (транслирует JS в машинный код), превращающая JavaScript из узкоспециализированного языка в язык общего назначения. Node.js добавляет возможность JavaScript взаимодействовать с устройствами ввода-вывода через свой API (на C++), подключать другие библиотеки, написанные на разных языках, обеспечивая вызовы к ним из JS-кода
Предоставить естественную неблокирующую, событийно-ориентированную инфраструктуру для написания программ с высокой конкурентностью (с) Ryan Dahl
Много I/O
Realtime
// Загружаем модуль http
var http = require('http');
// Создаем web-сервер с обработчиком запросов
var server = http.createServer(function (req, res) {
console.log('Начало обработки запроса');
// Передаем код ответа и http-заголовки
res.writeHead(200, {
'Content-Type': 'text/plain; charset=UTF-8'
});
res.end('Hello world!');
});
// Запускаем web-сервер
server.listen(2002, "127.0.0.1", function () {
console.log('Сервер запущен http://127.0.0.1:2002/');
});
>node -v //9.5.0
>node --version //9.5.0
>node
>console.log('Hello world');
//Hello world
//создаем файл index.js
console.log('Hello World');
>node index.js
//Hello World
По умолчанию npm будет устанавливать все пакеты в локальном каталоге, в котором вы сейчас работаете
install | установка пакета |
search | поиск пакета |
view | просмотр информации о пакете |
uninstall | удаление пакета |
link | устанавливает связь между пакетами |
unlink | удаляет связь между пакетами |
init | инициализация нового пакета |
publish | публикация пакета в репозитории |
unpublish | удаление пакета из репозитория |
owner | изменение прав доступа к пакету в репозитории |
adduser | добавление нового пользователя |
list | список установленных пакетов |
update | обновление пакета либо самого npm |
config | установка параметров конфигурации |
>npm install 'package name'
>npm install -g 'package name'
>npm install --global 'package name'
>npm install -g gulp
>npm install gulp@3.9.1
> npm install uglify-js --global
└─┬ uglify-js@2.6.2
├── async@0.2.10
├── source-map@0.5.3
├── uglify-to-browserify@1.0.2
└─┬ yargs@3.10.0
├── camelcase@1.2.1
├─┬ cliui@2.1.0
│ ├─┬ center-align@0.1.3
│ │ ├─┬ align-text@0.1.4
│ │ │ ├─┬ kind-of@3.0.2
│ │ │ │ └── is-buffer@1.1.2
│ │ │ ├── longest@1.0.1
│ │ │ └── repeat-string@1.5.4
│ │ └── lazy-cache@1.0.3
│ ├── right-align@0.1.3
│ └── wordwrap@0.0.2
├─┬ decamelize@1.1.2
│ └── escape-string-regexp@1.0.5
└── window-size@0.1.0
>npm search 'package name'
//не удобно
//лучше использовать ui интерфейс
https://www.npmjs.com/search?q=gulp
>npm view 'package name'
>npm view gulp
{ name: 'gulp',
description: 'The streaming build system',
dist-tags: { latest: '3.9.1' },
versions:
[ '0.0.1',
'0.0.2',
......
]
author: 'Fractal (http://wearefractal.com/)',
repository: {
type: 'git',
url: 'git+https://github.com/gulpjs/gulp.git' },
users:
{ jden: true,
stevelacy: true,
.....
}
}
>npm update [-g] 'package name' //latest version
>npm update -g gulp
>npm update -g npm
>npm config set 'key' 'value' [--global]
>npm config get 'key'
>npm config delete 'key'
>npm config list
>npm config edit npm c [set|get|delete|list]
>npm get 'key'
>npm set 'key' 'value' [--global]
>npm set init.author.name "maks"
>npm set init.author.email "test@gmail.com"
>npm set init.author.url "https://google.com"
>npm uninstall 'package name' [@ver] [--save| [--save-dev] [--global]
//--save пакет будет удален из dependencies
//--save-dev пакет будет удален из devDependencies
>npm uninstall sax --save
>npm uninstall gulp --global
>npm uninstall node-tap --save-dev
>npm uninstall dtrace-provider --save-optional
>npm list [--global] [--depth]
>npm list -g --depth=0
//без лишних зависимостей
├── npm@3.7.5
└── uglify-js@2.6.2
Файл содержит в себе информацию о приложении: название, версию, зависимости и тому подобное. Любая директория, в которой есть этот файл, интерпретируется как Node.js-пакет, даже если вы не собираетесь публиковать его
name | имя пакета |
description | описание пакета |
version | версия пакета |
keywords | набор ключевых слов |
author | информация об авторе пакета |
main | главный файл пакета |
license | тип лицензии |
dependencies | все пакеты, от которых зависит текущий пакет (production) |
devDependencies | все пакеты, от которых зависит текущий пакет (development) |
repository | тип репозитория и ссылка на него |
config | установка параметров конфигурации |
{
"name": "ddwa",
"version": "1.0.0",
"description": "",
"main": "index.html",
"scripts": {
"build": "gulp build"
},
"author": "Maksim Hladki",
"license": "MIT",
"devDependencies": {
"del": "^2.2.2",
"gulp": "^3.9.1",
"gulp-autoprefixer": "^3.1.1",
"gulp-clean-css": "^2.3.2",
"gulp-concat": "^2.6.1",
"gulp-connect": "^5.0.0",
.........
}
}
MAJOR.MINOR.PATCH
{ "dependencies" :
{
"foo" : "1.0.0 - 2.9999.9999",
"bar" : ">=1.0.2 <2.1.2",
"baz" : ">1.0.2 <=2.3.4",
"boo" : "2.0.1",
"qux" : "<1.0.0 || >=2.3.1 <2.4.5 || >=2.5.2 <3.0.0",
"asd" : "http://asdf.com/asdf.tar.gz",
"til" : "~1.2",
"elf" : "~1.2.3",// >= 1.2.3 < 1.3.0
"tra" : "^1.2.1",// >= 1.2.1 < 2.0.0
"two" : "2.x",
"thr" : "3.3.x",
"lat" : "latest",
"dyl" : "file:../dyl"
}
}
{
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"ansi-gray": {
"version": "0.1.1",
"resolved": "https://registry.npmjs.org/ansi-gray/-/ansi-gray-0.1.1.tgz",
"integrity": "sha1-KWLPVOyXksSFEKPetSRDaGHvclE=",
"dev": true,
"requires": {
"ansi-wrap": "0.1.0"
}
},
"ansi-regex": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
"dev": true
},
............................
Менеджер пакетов, ориентированный на применении в разработке клиентской части веб-приложений с использованием JS библиотек и фреймворков
>npm install -g bower
//установка пакета angular
>bower install angular
//установка пакета из репозитория
>bower install git://github.com/angular/angular.js/
>bower install jquery
>bower cloning git://github.com/components/jquery.git
>bower cached git://github.com/components/jquery.git
>bower fetching jquery
>bower checking out jquery#2.0.0
>bower copying /Users/danheberden/.bower/cache/jquery/29cb...
>bower installing jquery#2.0.0
Главное отличие — подход к установке зависимостей пакетов. Npm устанавливает зависимости для каждого пакета отдельно, в папку этого пакета, потом так же ставит зависимости зависимостей и так далее. В frontend-разработке это недопустимо: нельзя подключить на страницу две версии библиотеки
В Бовере каждый пакет устанавливается один раз, и в случае конфликта зависимостей Бовер просто не станет устанавливать пакет, несовместимый с уже установленными
Данное ограничение npm было устранено в 2016 году
search | поиск пакета по имени |
install | установка пакета |
list | список установленных пакетов |
update | обновление выбранного пакета |
uninstall | удаление пакета |
init | инициализация конфигурационного файла bower.json |
>bower search jquery
Search results:
jQuery https://github.com/jquery/jquery.git
jquery https://github.com/jquery/jquery-dist.git
jquery.x https://github.com/jljLabs/jquery.x.git
jt_jquery https://github.com/vicanso/jt_jquery.git
jquery.Q https://github.com/jsbuzz/jQuery_Q.git
jquery-m https://github.com/meetup/jquery.git
jquery.j2d https://github.com/fsggs/jquery.j2d.git
jquery.hx https://github.com/millennialmedia/jquery.hx.git
jquery-ts https://github.com/andraaspar/jquery-ts.git
jquery-tm https://github.com/trymore/jquery-tm.git
jquery.gk https://github.com/ezoapp/jquery.gk.git
jquery-jec https://github.com/RaYell/jquery-jec.git
........
>bower install jquery#2.0.0
//result
bower jquery#2.0.0 not-cached https://github.com/jquery/jquery-dist.git#2.0.0
bower jquery#2.0.0 resolve https://github.com/jquery/jquery-dist.git#2.0.0
bower jquery#2.0.0 download https://github.com/jquery/jquery-dist/2.0.0.tar.gz
bower jquery#2.0.0 extract archive.tar.gz
bower jquery#2.0.0 resolved https://github.com/jquery/jquery-dist.git#2.0.0
jquery#2.0.0 bower_components\jquery
>bower list
//result
bower check-new Checking for new versions of the project dependencies...
HP C:\Users\HP
└── jquery#3.1.1 extraneous
>bower uninstall jquery
>bower init
//bower.json
{
name: 'Maks Hladki',
authors: [
'Maks Hladki <MaksHladki@gmail.com>'
],
description: 'test project',
main: 'index.html',
keywords: [
'js',
'frontend'
],
license: 'MIT',
homepage: 'https://github.com/MaksHladki/DDWA'.
dependencies: {
"jquery": "~3.1.1",
},
devDependencies: {}
}
psst! While Bower is maintained, we recommend using Yarn and Webpack for front-end projects read how to migrate!
Менеджер пакетов, совместно созданный Facebook, Google, Exponent и Tilde. Является современной альтернативой пакетного менеджера npm, отличается высокой скоростью, надежностью и безопасностью
Пакет | npm 4 | npm 5 | Yarn |
---|---|---|---|
express | 8 сек. | 6 сек. | 5.5 сек. |
gulp | 11 сек. | 9 сек. | 8 сек. |
init | инициализация нового пакета (создает файл package.json) |
install | устанавливает все зависимости из файла package.json |
add | добавляет пакет и устанавливает зависимости |
upgrade | обновляет пакеты до последней/определенной версии |
remove | удяляет пакет и зависимости из package.json и yarn.lock |
licenses | выводит список лицензий всех установленных в проекте пакетов |
why | проверяет граф зависимостей и выясняет, почему указанный пакет установлен в проекте |
generate-lock-entry | генерирует файл yarn.lock на основе зависимостей из package.json (похоже на npm shrinkwrap) |
config | устанавливает конфигурационные значения в виде пар ключ-значение |
list | выводит список зависимостей |
pack | создает gzip-архив зависимостей |
publish | позволяет опубликовать пакет в npmjs.com |
global | позволяет выполнять команды add, bin, list и remove в глобальной области |
yarn init [--yes]
>yarn init
yarn init v1.3.2
question name (DDWA): DDWA
question version (1.0.0): 0.0.7
question description: Development of dynamic web applications
question entry point (index.js): index.js
question repository url: https://github.com/MaksHladki/DDWA
question author: Maksim Hladki
question license (MIT): MIT
question private: without private key
success Saved package.json
Done in 19.30s.
yarn install [--check-files] [--ignore-scripts] [--force]
>yarn install
yarn install v1.3.2
info No lockfile found.
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
info Lockfile not saved, no dependencies.
Done in 0.34s.
yarn add [package-name] [--dev/-D]
yarn add [package]@[version]
>yarn add gulp --dev
yarn add v1.3.2
[1/4] Resolving packages...
warning gulp > gulp-util@3.0.8: gulp-util is deprecated
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved lockfile.
success Saved 200 new dependencies.
├─ ansi-regex@2.1.1
├─ ansi-wrap@0.1.0
├─ archy@1.0.0
....
├─ vinyl-fs@0.3.14
├─ vinyl@0.4.6
├─ which@1.3.0
└─ xtend@4.0.1
Done in 16.12s.
yarn upgrade [package]
yarn upgrade [package]@[version]
>yarn upgrade gulp@3.9.0
yarn upgrade v1.3.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Rebuilding all packages...
success Saved lockfile.
success Saved 2 new dependencies.
├─ gulp@3.9.0
└─ interpret@0.6.6
Done in 4.18s.
yarn remove [package] --[flag]
>yarn remove gulp
yarn remove v1.3.2
[1/2] Removing module gulp...
[2/2] Regenerating lockfile and installing missing dependencies...
success Uninstalled packages.
Done in 1.78s.
yarn global add/bin/list/remove/upgrade [--prefix]
>yarn global add gulp
yarn global v1.3.2
[1/4] Resolving packages...
warning gulp > gulp-util@3.0.8: gulp-util is deprecated
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Installed "gulp@3.9.1" with binaries:
- gulp
Done in 9.05s.
>yarn add jquery
>yarn add jquery
yarn add v1.3.2
[1/4] Resolving packages...
error An unexpected error occurred:
"https://registry.yarnpkg.com/jquery:
getaddrinfo ENOENT registry.yarnpkg.com:443".
>yarn add jquery --offline
yarn add v1.3.2
[1/4] Resolving packages...
[2/4] Fetching packages...
[3/4] Linking dependencies...
[4/4] Building fresh packages...
success Saved 1 new dependency.
└─ jquery@3.3.1
Done in 0.58s.
Позволяет получить согласованную установку зависимостей на разных машинах путем фиксации конкретной версии каждого пакета
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
jquery@^3.3.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/jquery/-/jquery-3.3.1.tgz#958ce29e81c9790f31be7792df5d4d95fc57fbca"
Develop | Build |
---|---|
Watch | Testing |
Live Reload | Compile |
ES6/TypeSctipt/Coffee | Concat |
Sass/Less | Rename |
JsHint | Minify |
Image optimization | |
Deployment |
Gulp | Grunt |
---|---|
ориентирован на поток | ориентирован на файл |
запускает задачи параллельно | запускает задачи последовательно |
синтаксис более краток и лаконичен | основан на конфигурации |
проектировался для больших проектов | проектировался для средних и небольших проектов |
скорость выполнения выше |
├── app/
├── css/
├── fonts/
├── images/
├── index.html
├── js/
└── scss/
├── dist/
├── gulpfile.js
├── node_modules/
└── package.json
├── .tmp
│ ├── app.css
│ ├── app.js
│ └── index.html
├── bower_components
│ └── angular
├── dist
│ ├── app.min.css
│ ├── app.min.js
│ └── index.html
├── src
├── app.scss
├── app.ts
├── components
└── index.html
├── gulpfile.js
├── node_modules/
└── package.json
Предпочитая код конфигурации, Gulp оставляет простые задачи простыми, а из сложных делает управляемые
const gulp = require('gulp'),
coffee = require('gulp-coffee'),
concat = require('gulp-concat'),
cssmin = require('gulp-cssmin');
gulp.task('coffee', () => {
//TODO
});
Используя преимущества потока данных, процесс выполнения задач получается более быстрым, промежуточные файлы не создаются и на диск не записываются (Vinul FS)
gulp.task('html', () => {
return gulp.src(srcPath.html)// Считываем файл с диска
.pipe(useref()) //Обрабатываем в оперативной памяти
.pipe(gulpif('*.js', uglify())) //Обрабатываем в ОП
.pipe(gulpif('*.css',
pipe(
autoprefixer({
browsers: ['last 2 versions']
}),
cssmin()
)
))// Обрабатываем в оперативной памяти
.pipe(gulp.dest(distPath.html))// Записываем файл на диск
.pipe(connect.reload());
});
Все плагины для Gulp пишутся по специальным правилам. Этот процесс позволяет задачам оставаться простыми и работать так, как этого ожидает разработчик
Общее количество плагинов на декабрь 2016: 1100+
Можно начать работать с Gulp с минимальными знаниями API. Нужно всего лишь понимать принцип работы основных четырех функций: task, watch, src и dest
>npm install --global gulp
>npm install --save-dev gulp
var gulp = require('gulp');
gulp.task('default', function() {
console.log('Gulp is running!');
});
>gulp
[16:20:01] Using gulpfile G:\test\gulpfile.js
[16:20:01] Starting 'default'...
Gulp is running!
[16:20:01] Finished 'default' after 200 µs
>gulp default
//если имя задачи не установлено, вызывается задача с именем default
[16:21:17] Using gulpfile G:\test\gulpfile.js
[16:21:17] Starting 'default'...
Gulp is running!
[16:21:17] Finished 'default' after 181 µs
gulp.task(name[, deps], fn)
//name - required
//deps - массив зависимых зависимостей
//fn - callback вызова
gulp.task('hello', function() {
console.log('Hello world!');
});
gulp.task('css', ['greet'], function () {
//TODO
});
gulp.task('build', ['css', 'js', 'imgs']);
gulp.task('default', function () {
//TODO default task
});
gulp.watch(glob[, opts, fn])
//globs - строка или массив
//options - доп. параметры или callback
gulp.watch('js/**/*.js', function(event) {
console.log('File ' + event.path + ' type ' + event.type);
});
gulp.task('watch', function(){
gulp.watch('app/scss/**/*.scss', ['sass']);
gulp.watch('app/css/**/*.css', ['css']);
gulp.watch('app/js/**/*.js', ['js']);
// Other watchers
});
gulp.src(globs[, options])
//globs - строка или массив
//options - доп. параметры
//возвращает входной поток
gulp.src('./*.jade')
gulp.src('*.+(js|css)')
gulp.src('*.{jpg,jpeg,png,gif}')
gulp.src(['js/**/*.js', '!js/**/*.min.js'])
gulp.dest(path, [,options])
//принимает путь к файлу и возвращает исходящий поток
gulp.task('css', () => {
return gulp.src(srcPath.css)
.on('data', (file) => {
console.log({
path:file.path,
basename: file.basename
});
})
.pipe(sourcemaps.init())
.pipe(autoprefixer(autoprefixerSettings))
.pipe(cleanCSS(cleanCSSSettings))
.pipe(sourcemaps.write())
.pipe(gulp.dest(distPath.css));
});
.pipe(destination)
//возвращает поток
//destination - тоже поток
gulp.src('./client/templates/*.jade')
.pipe(jade())
.pipe(gulp.dest('./app'))
.pipe(minify())
.pipe(gulp.dest('./dist'));
>npm install browser-sync gulp --save-dev
const gulp = require('gulp'),
browserSync = require('browser-sync').create();
gulp.task('html', () => {
return gulp.src('src/**/*.html').pipe(gulp.dest('dist/'));
});
gulp.task('css', () => {
return gulp.src("src/css/*.css")
.pipe(gulp.dest("dist/css"))
.pipe(browserSync.stream());//*
});
gulp.task('serve', ['html' ,'css'], () => {
browserSync.init({ server: "./dist" });
});
gulp.task('watch', () => {
gulp.watch('src/css/*.css', ['css']);
gulp.watch('src/**/*.html', ['html'])
.on('change', browserSync.reload);//*
});
gulp.task('default', ['serve', 'watch']);
gulp.task('serve', () => {
browserSync.init({
server: distPath.dist,
port: 4000
});
browserSync.watch(distPath.dist).on('change', browserSync.reload);
});
browserSync.reload();
browserSync.reload("styles.css");
browserSync.reload(["styles.css", "ie.css"]);
browserSync.reload("*.css");
//возвращает трансформированный поток данных,
//автоматически вставляемых в браузер
gulp.task('sass', function () {
return gulp.src('scss/styles.scss')
.pipe(sass({includePaths: ['scss']}))
.pipe(gulp.dest('css'))
.pipe(browserSync.stream());
//автоматически вставляет трансформированный поток в браузер
});
.pipe(browserSync.stream({once: true}));
// перегружает только один раз для потока данных
//(исходных файлов может быть несколько)
.pipe(browserSync.stream({match: "**/*.css"}));
//фильтр обновления только определенных файлов
var browserSync = require("browser-sync").create();
// запускаем сервер
browserSync.init({server: "./app"});
// останавливаем сервер через 5 секунд
setTimeout(function () {
browserSync.exit();
}, 5000);
browserSync.init({
server: "./dist",
port: 8000,
index: 'index.html',
//proxy: "localhost:8888",
browser: ["firefox"]
});
>npm install --save-dev gulp-connect
const gulp = require('gulp'),
connect = require('gulp-connect');
gulp.task('html', () => {
return gulp.src('src/**/*.html')
.pipe(gulp.dest('dist/'))
.pipe(connect.reload()); //*
})
gulp.task('serve', ['html'], () => {
connect.server({
root: 'dist', livereload: true //*
});
});
gulp.task('watch', () => {
gulp.watch('src/**/*.html', ['html']);
});
gulp.task('default', ['serve', 'watch']);
gulp.task('something', function() {
connect.server({
port: 8888
});
//BODY
connect.serverClose();
});
gulp.task('serve', ['html'], () => {
connect.server({
name: 'Test application',
root: ['dist', 'tmp'],
port: 8000,
livereload: true,
index: 'index.html'
});
});
>npm install --save-dev gulp-autoprefixer
const gulp = require('gulp'),
autoprefixer = require('gulp-autoprefixer');
gulp.task('css', () =>
gulp.src('src/app.css')
.pipe(autoprefixer({
browsers: ['last 2 versions']
}))
.pipe(gulp.dest('dist/css/'))
);
a {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex
}
const gulp = require('gulp'),
sourcemaps = require('gulp-sourcemaps'),
autoprefixer = require('gulp-autoprefixer'),
concat = require('gulp-concat');
gulp.task('css', () =>
gulp.src('src/**/*.css')
.pipe(sourcemaps.init())
.pipe(autoprefixer())
.pipe(concat('all.css'))
.pipe(sourcemaps.write('.'))
.pipe(gulp.dest('dist/css/'))
);
autoprefixer(
{
browsers: ['last 2 versions', 'ie 9', '> 1%'],
cascade: true, //визуальный каскад, если css не сжат
supports: false,//добавлять префикс к @supports параметрам,
stats: { //собственная статистика
"ie": {
"6": 0.01,
"7": 0.4,
"8": 1.5
},
"chrome": {
…
},
…
}
}
)
|
|
|
|
>npm install gulp-clean-css --save-dev
const gulp = require('gulp'),
cleanCSS = require('gulp-clean-css');
gulp.task('css', () => {
return gulp.src('app/styles/*.css')
.pipe(cleanCSS({compatibility: 'ie8'}))//ie8, * или '' для ie9+
.pipe(gulp.dest('dist/'));
});
const gulp = require('gulp'),
cleanCSS = require('gulp-clean-css');
gulp.task('css', function() {
return gulp.src('app/styles/*.css')
.pipe(cleanCSS({debug: true}, (details) => {
console.log(details.name + ': ' + details.stats.originalSize);
console.log(details.name + ': ' + details.stats.minifiedSize);
}))
.pipe(gulp.dest('dist/css/'));
});
const gulp = require('gulp'),
cleanCSS = require('gulp-clean-css'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('css', function() {
return gulp.src('app/styles/*.css')
.pipe(sourcemaps.init())
.pipe(cleanCSS())
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/css/'));
});
});
>npm install gulp-sass --save-dev
const gulp = require('gulp'),
sass = require('gulp-sass');
gulp.task('sass', () => {
return gulp.src('./sass/**/*.scss')
.pipe(sass().on('error', sass.logError))
.pipe(gulp.dest('./css'));
});
gulp.task('watch', () => {
gulp.watch('./sass/**/*.scss', ['sass']);
});
const gulp = require('gulp'),
sass = require('gulp-sass');
gulp.task('sass', () => {
return gulp.src('./sass/**/*.scss')
.pipe(sass.sync().on('error', sass.logError))
//выполняется синхронно
.pipe(gulp.dest('./css'));
});
gulp.task('watch', () => {
gulp.watch('./sass/**/*.scss', ['sass']);
});
const gulp = require('gulp'),
sass = require('gulp-sass'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('sass', function () {
return gulp.src('./sass/**/*.scss')
.pipe(sourcemaps.init())
.pipe(sass().on('error', sass.logError))
.pipe(sourcemaps.write())
.pipe(gulp.dest('./css'));
});
>npm install gulp-less --save-dev
const gulp = require('gulp'),
less = require('gulp-less');
gulp.task('less', () => {
return gulp.src('./less/**/*.less')
.pipe(less())
.pipe(gulp.dest('./public/css'));
});
const gulp = require('gulp'),
less = require('gulp-less'),
LessAutoprefix = require('less-plugin-autoprefix');
const autoprefix = new LessAutoprefix({ browsers: ['last 2 versions'] });
gulp.task('less', () => {
return gulp.src('./less/**/*.less')
.pipe(less({
plugins: [autoprefix]
}))
.pipe(gulp.dest('./public/css'));
});
const gulp = require('gulp'),
less = require('gulp-less'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('less', () => {
return gulp.src('./less/**/*.less')
.pipe(sourcemaps.init())
.pipe(less())
.pipe(sourcemaps.write())
.pipe(gulp.dest('./public/css'));
});
>npm install --save-dev gulp-concat
const gulp = require('gulp'),
concat = require('gulp-concat');
gulp.task('scripts', () => {
return gulp.src('src/js/*.js')
.pipe(concat('bundle.js'))
.pipe(gulp.dest('dist/js/'));
});
const gulp = require('gulp'),
concat = require('gulp-concat'),
sourcemaps = require('gulp-sourcemaps');
gulp.task('css', () => {
return gulp.src('src/**/*.css')
.pipe(sourcemaps.init())
.pipe(concat('bundle.css'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist/'));
});
>npm install --save-dev gulp-imagemin
const gulp = require('gulp'),
imagemin = require('gulp-imagemin');
gulp.task('img', () =>
gulp.src('src/img/*')
.pipe(imagemin())
.pipe(gulp.dest('dist/img/'))
);
const gulp = require('gulp'),
imagemin = require('gulp-imagemin');
gulp.task('img', () =>
gulp.src('src/img/*')
.pipe(imagemin(
[ imagemin.gifsicle(),
imagemin.jpegtran(),
imagemin.optipng(),
imagemin.svgo()
],
{ verbose: true})
)
.pipe(gulp.dest('dist/img/'))
);
[10:43:01] gulp-imagemin: ✔ vs-code-bower.png (saved 2.97 kB - 11.1%)
[10:43:01] gulp-imagemin: ✔ window.png (saved 11.6 kB - 13.3%)
|
|
…
.pipe(imagemin([
imagemin.gifsicle({interlaced: true}),
imagemin.jpegtran({progressive: true}),
imagemin.optipng({optimizationLevel: 5}),
imagemin.svgo({
plugins: [
{removeViewBox: true},
{cleanupIDs: false}
]
})
]))
…
>npm install gulp-rename --save-dev
const gulp = require('gulp'),
rename = require("gulp-rename");
gulp.task('rename', () => {
return gulp.src('./src/css/main.css')
.pipe(rename('css/bundle.css'))
.pipe(gulp.dest('./dist'));
});
const gulp = require('gulp'),
rename = require("gulp-rename");
gulp.task('rename', () => {
return gulp.src('./src/css/main.css')
.pipe(rename(function (path) {
path.dirname += '/base';
path.basename += '-bundle';
path.extname = '.css'
}))
.pipe(gulp.dest('./dist'));
//dist/css/base/main-bundle.css
});
const gulp = require('gulp'),
rename = require("gulp-rename");
gulp.task('rename', () => {
return gulp.src("./src/css/main.css")
.pipe(rename(
{
dirname: "main/",
basename: "main",
prefix: "style-",
suffix: ".min",
extname: ".css"
}
))
.pipe(gulp.dest("./dist"));
//dist/css/main/style-main.min.css
});
>npm install --save-dev gulp-babel
>npm install --save-dev babel-preset-es2015 //*
const gulp = require('gulp'),
babel = require('gulp-babel');
gulp.task('default', () =>
gulp.src('src/app.js')
.pipe(babel({
presets: ['es2015']
}))
.pipe(gulp.dest('dist'))
);
const gulp = require('gulp'),
sourcemaps = require('gulp-sourcemaps'),
babel = require('gulp-babel'),
concat = require('gulp-concat');
gulp.task('default', () =>
gulp.src('src/**/*.js')
.pipe(sourcemaps.init())
.pipe(babel({
presets: ['es2015']
}))
.pipe(concat('all.js'))
.pipe(sourcemaps.write())
.pipe(gulp.dest('dist'))
);
>npm install --save-dev babel-plugin-transform-runtime
const gulp = require('gulp'),
babel = require('gulp-babel');
gulp.task('default', () =>
gulp.src('src/app.js')
.pipe(babel({
plugins: ['transform-runtime']
}))
.pipe(gulp.dest('dist'))
);
>npm install --save-dev gulp-uglify
const gulp = require('gulp'),
uglify = require('gulp-uglify');
gulp.task('compress', () => {
return gulp.src('lib/*.js')
.pipe(uglify())
.pipe(gulp.dest('dist/'))
});
const gulp = require('gulp'),
uglify = require('gulp-uglify');
gulp.task('compress', () => {
return gulp.src('lib/*.js')
.pipe(uglify({
mangle: false,
output: {
beautify: true,
comments: true
},
compress: {
drop_debugger : false,
warnings : false,
loops : true
}
}))
.pipe(gulp.dest('dist/'))
});
indent_start : 0, //start indentation on every line
indent_level : 4, //indentation level
quote_keys : false,//quote all keys in object literals?
space_colon : true, //add a space after colon signs?
ascii_only : false,//output ASCII-safe?
inline_script: false,//escape "</script"?
width : 80, //informative maximum line width
max_line_len : 32000,//maximum line length
ie_proof : true, //output IE-safe code?
beautify : false,//beautify output?
source_map : null, //output a source map
bracketize : false,//use brackets every time?
comments : false,//output comments?
semicolons : true, //use semicolons to separate statements?
sequences : true, //join consecutive statemets with “comma operator”
properties : true, //optimize property access: a["foo"] → a.foo
dead_code : true, //discard unreachable code
drop_debugger: true, //discard “debugger” statements
unsafe : false,//some unsafe optimizations (see below)
conditionals : true, //optimize if-s and conditional expressions
comparisons : true, //optimize comparisons
evaluate : true, //evaluate constant expressions
booleans : true, //optimize boolean expressions
loops : true, //optimize loops
unused : true, //drop unused variables/functions
hoist_funs : true, //hoist function declarations
hoist_vars : false,//hoist variable declarations
if_return : true, //optimize if-s followed by return/continue
join_vars : true, //join var declarations
cascade : true, //try to cascade `right` into `left` in sequences
side_effects : true, //drop side-effect-free statements
warnings : true, //warn about potentially dangerous optimizations
global_defs : {} //global definitions
>npm install --save del
const gulp = require('gulp'),
del = require('del');
gulp.task('clean', () => {
return del([distPath.dist]);
});
const gulp = require('gulp'),
del = require('del');
gulp.task('clean', () => {
return del(['dist/css/', 'dist/js/**/*.min.js']).then(paths => {
console.log('Deleted files and folders:\n', paths.join('\n'));
});
});
>npm install gulp-if --save-dev
const gulp = require('gulp'),
gulpif = require('gulp-if'),
uglify = require('gulp-uglify');
var condition = true;
//условие, может быть функция, паттерн и т.д
gulp.task('task', function() {
gulp.src('./src/*.js')
.pipe(gulpif(condition, uglify()))
.pipe(gulp.dest('./dist/'));
});
const gulp = require('gulp'),
gulpIgnore = require('gulp-ignore'),
gulpif = require('gulp-if'),
autoprefixer = require('gulp-autoprefixer'),
cleanCSS = require('gulp-clean-css'),
uglify = require('gulp-uglify');
const autoprefixerSettings = {};
const cleanCSSSettings = {};
gulp.task('html', () => {
return gulp.src('src/**/*.*')
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css',
pipe(
autoprefixer(autoprefixerSettings),
cleanCSS(cleanCSSSettings)
)
))
.pipe(gulp.dest('dist/'));
});
>npm install --save-dev gulp-useref
const gulp = require('gulp'),
useref = require('gulp-useref');
gulp.task('html', function () {
return gulp.src('src/**/*.html')
.pipe(useref())
.pipe(gulp.dest('dist'));
});
const gulp = require('gulp'),
useref = require('gulp-useref'),
gulpif = require('gulp-if'),
uglify = require('gulp-uglify'),
cleanCSS = require('gulp-clean-css');
gulp.task('html', function () {
return gulp.src('src/*.html')
.pipe(useref())
.pipe(gulpif('*.js', uglify()))
.pipe(gulpif('*.css', cleanCSS()))
.pipe(gulp.dest('dist'));
});
...список js или css файлов
<!-- build:css css/bundle.min.css -->
<link rel="stylesheet" href="css/reveal.css">
<link rel="stylesheet" href="css/reveal.font.css">
<link rel="stylesheet" href="css/reveal.theme.css">
<link rel="stylesheet" href="css/font-awesome.css">
<!-- endbuild -->
>npm install --save-dev gulp-sequence
const gulp = require('gulp'),
gulpSequence = require('gulp-sequence');
gulp.task('a', () => { /* callback code */ });
gulp.task('b', () => { /* callback code */ });
gulp.task('c', () => { /* callback code */ });
gulp.task('d', () => { /* callback code */ });
gulp.task('e', () => { /* callback code */ });
gulp.task('sequence-1', gulpSequence(['a', 'b'], 'c', ['d', 'e']));
gulp.task('sequence-2', (cb) => {
gulpSequence('a', ['b', 'c', 'd'], 'e', cb);
});
gulp.task('sequence-3', (cb) => {
gulpSequence(['a', 'b', 'e'], 'd', 'c')(cb);
});
gulp.task('build', gulpSequence('clean', [
'html',
'img',
'js',
'css'
]));
gulp.task('default', gulpSequence('build', ['watch', 'connect']));
>npm install --save-dev gulp-watch
const gulp = require('gulp'),
watch = require('gulp-watch');
gulp.task('stream', () => {
return watch('css/**/*.css', { ignoreInitial: false })//*
//ignoreInitial event add/add folder будут вызваны
.pipe(gulp.dest('build'));
});
gulp.task('callback', () => {
return watch('css/**/*.css', () => {//*
gulp.src('css/**/*.css')
.pipe(gulp.dest('build'));
});
});
gulp.task('watch', () => {
watch(srcPath.css, () => gulp.start('css'));
watch(srcPath.html, () => gulp.start('html'));
watch(srcPath.js, () => gulp.start('js'));
watch(srcPath.img, () => gulp.start('img'));
watch(srcPath.font, () => gulp.start('font'));
watch(srcPath.task, () => gulp.start('task'));
});
>npm install jshint gulp-jshint --save-dev
const gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('js:hint', function () {
return gulp.src('./src/js/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter());
});
src\js\classList.min.js: line 2, col 95, Missing "use strict" statement.
src\js\classList.min.js: line 2, col 1499, Unnecessary semicolon.
src\js\classList.min.js: line 2, col 389, 'DOMException' is not defined.
src\js\classList.min.js: line 2, col 1492, 'self' is not defined.
const gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('js:lint', () => {
return gulp.src('./src/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('jslint_xml'));
});
[22:00:39] Using gulpfile C:\Projects\DDWA\gulpfile.js
[22:00:39] Starting 'js:lint'...
<?xml version="1.0" encoding="utf-8"?>
<checkstyle version="4.3">
<file name="src\js\classList.min.js">
<error line="2"
column="95"
severity="error"
message="Missing "use strict" statement."
source="jshint.E007" />
const gulp = require('gulp'),
jshint = require('gulp-jshint');
gulp.task('js:hint', () => {
return gulp.src('./src/**/*.js')
.pipe(jshint())
.pipe(jshint.reporter('checkstyle'))
.pipe(jshint.reporter('fail'));//*
});
const gulp = require('gulp'),
jshint = require('gulp-jshint'),
jshintReporter = require('gulp-jshint-html-reporter');
gulp.task('js:hint', () => {
return gulp.src('./src/**/*.js')
.pipe(jshint('.jshintrc'))//*
.pipe(jshint.reporter(jshintReporter, {//*
filename: './src/code-analysis/js/jshint-output.html',
createMissingFolders : true
}));
});
{
"bitwise": true,
"camelcase": true,
"curly": true,
"eqeqeq": true,
"es3": false,
"forin": true,
"freeze": true,
"immed": true,
"indent": 4,
"latedef": "nofunc",
"newcap": true,
"noarg": true,
"noempty": true,
"nonbsp": true,
"nonew": true,
"plusplus": false,
"quotmark": "single",
"undef": true,
"unused": false,
"strict": false,
"maxparams": 10,
"maxdepth": 5,
"maxstatements": 40,
"maxcomplexity": 8,
"maxlen": 120,
"asi": false,
"boss": false,
"debug": false,
"eqnull": true,
"esnext": false,
"evil": false,
"expr": false,
"funcscope": false,
"globalstrict": false,
"iterator": false,
"lastsemic": false,
"laxbreak": false,
"laxcomma": false,
"loopfunc": true,
"maxerr": false,
"moz": false,
"multistr": false,
"notypeof": false,
"proto": false,
"scripturl": false,
"shadow": false,
"sub": true,
"supernew": false,
"validthis": false,
"noyield": false,
"browser": true,
"node": true,
"globals": {
"angular": false,
"$": false
}
}
>npm install --save-dev gulp-csslint
const gulp = require('gulp'),
csslint = require('gulp-csslint');
gulp.task('css:lint', () => {
return gulp.src('./src/**/*.css')
.pipe(csslint())
.pipe(csslint.formatter());
});
[22:12:31] Using gulpfile C:\Projects\DDWA\gulpfile.js
[22:12:33] Starting 'css:lint'...
csslint: There are 15 problems in C:\Projects\DDWA\src\css\font-awesome.css.
font-awesome.css
1: warning at line 7, col 1
Rule doesn't have all its properties in alphabetical order.
const gulp = require('gulp'),
csslint = require('gulp-csslint');
gulp.task('css:lint', () => {
return gulp.src('./src/**/*.css')
.pipe(csslint())
.pipe(csslint.formatter('junit-xml'));
});
const gulp = require('gulp'),
csslint = require('gulp-csslint');
gulp.task('css:lint', () => {
return gulp.src('./src/**/*.css')
.pipe(csslint())
.pipe(csslint.formatter());
.pipe(csslint.formatter('fail'));
});
//modules
const gulp = require('gulp'),
gulpif = require('gulp-if'),
gulpSequence = require('gulp-sequence'),
autoprefixer = require('gulp-autoprefixer'),
browserSync = require('browser-sync'),
concat = require('gulp-concat'),
cleanCSS = require('gulp-clean-css'),
del = require('del'),
imagemin = require('gulp-imagemin'),
lazypipe = require('lazypipe'),
newer = require('gulp-newer'),
rename = require('gulp-rename'),
pipe = require('multipipe'),
sourcemaps = require('gulp-sourcemaps'),
uglify = require('gulp-uglify'),
useref = require('gulp-useref'),
watch = require('gulp-watch');
//variables
const srcPath = {
'src': './src',
'html': ['./src/**/*.html'],
'img': './src/**/*.+(jpg|png|svg|ico)',
'css': ['./src/!(css|js)*/**/*.css'],
'js': './src/!(js)*/**/*.js',
'font': './src/font/**/*.*',
'task': './src/task/**/*.pdf'
};
const distPath = {
'dist': './dist/',
'html': './dist/',
'img': './dist/',
'css': './dist/css/',
'js': './dist/',
'font': './dist/font/',
'task': './dist/task/'
};
const pluginSettings = {
autoprefixer: {
browsers: ['last 2 versions', 'ie 11']
},
cleanCSS: {
compatibility: '*'
},
imagemin: {
optimizationLevel: 2
}
};
//tasks
gulp.task('clean', () => {
return del([distPath.dist]);
});
gulp.task('html', () => {
return gulp.src(srcPath.html)
.pipe(newer(distPath.html))
.pipe(useref({}, lazypipe().pipe(sourcemaps.init)))
.pipe(gulpif('*.js', pipe(
uglify()
)))
.pipe(gulpif('*.css',
pipe(
autoprefixer(pluginSettings.autoprefixer),
cleanCSS(pluginSettings.cleanCSS)
)
))
.pipe(sourcemaps.write())
.pipe(gulp.dest(distPath.html));
});
gulp.task('css', () => {
return gulp.src(srcPath.css)
.pipe(sourcemaps.init())
.pipe(autoprefixer(pluginSettings.autoprefixer))
.pipe(cleanCSS(pluginSettings.cleanCSS))
.pipe(sourcemaps.write())
.pipe(gulp.dest(distPath.css));
});
gulp.task('js', () => {
return gulp.src(srcPath.js)
.pipe(gulp.dest(distPath.js));
});
gulp.task('img', () => {
return gulp.src(srcPath.img)
.pipe(newer(distPath.img))
.pipe(imagemin(pluginSettings.imagemin))
.pipe(gulp.dest(distPath.img));
});
gulp.task('font', () => {
return gulp.src(srcPath.font)
.pipe(gulp.dest(distPath.font));
});
gulp.task('task', () => {
return gulp.src(srcPath.task)
.pipe(gulp.dest(distPath.task));
});
gulp.task('serve', () => {
browserSync.init({
server: distPath.dist,
port: 4000
});
browserSync.watch(distPath.dist).on('change', browserSync.reload);
});
gulp.task('build', gulpSequence('clean', [
'html',
'img',
'js',
'css',
'font',
'task'
]));
gulp.task('watch', () => {
watch(srcPath.css, () => gulp.start('css'));
watch(srcPath.html, () => gulp.start('html'));
watch(srcPath.js, () => gulp.start('js'));
watch(srcPath.img, () => gulp.start('img'));
watch(srcPath.font, () => gulp.start('font'));
watch(srcPath.task, () => gulp.start('task'));
});
gulp.task('default', gulpSequence('build', ['watch', 'serve']));
>npm install webpack -g
>npm install webpack --save-dev
├── index.html
├── index.js
├── util.js
├── package.json
└── webpack.config.js
module.exports ={
entry: "./index.js",
output: {
path: __dirname + "/dist",
filename: "bundle.js"
},
optimization: {
minimize: false
}
}
util.js
function logger(msg) {
console.log('util.js: ' + msg);
}
exports.logger = logger;
index.js
const util = require('./util.js');
util.logger('test message!');
index.html
<!DOCTYPE>
<html>
<body>
<script src="dist/bundle.js"></script>
</body>
</html>
>webpack
Hash: d6d2f71e8c9a06fc28da
Version: webpack 4.0.1
Time: 837ms
Built at: 3/2/2018 10:45:39 AM
Asset Size Chunks Chunk Names
bundle.js 639 bytes 0 [emitted] main
Entrypoint main = bundle.js
[0] ./util.js 88 bytes {0} [built]
[1] ./index.js 65 bytes {0} [built]
//index.html console
util.js: test message!
(function(modules) { // webpackBootstrap
// The module cache
var installedModules = {};
// The require function
function __webpack_require__(moduleId) {
// Check if module is in cache
if(installedModules[moduleId]) {
return installedModules[moduleId].exports;
}
// Create a new module (and put it into the cache)
var module = installedModules[moduleId] = {
i: moduleId,
l: false,
exports: {}
};
// Execute the module function
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
// Flag the module as loaded
module.l = true;
// Return the exports of the module
return module.exports;
}
// expose the modules object (__webpack_modules__)
__webpack_require__.m = modules;
// expose the module cache
__webpack_require__.c = installedModules;
// define getter function for harmony exports
__webpack_require__.d = function(exports, name, getter) {
if(!__webpack_require__.o(exports, name)) {
Object.defineProperty(exports, name, {
configurable: false,
enumerable: true,
get: getter
});
}
};
// define __esModule on exports
__webpack_require__.r = function(exports) {
Object.defineProperty(exports, '__esModule', { value: true });
};
// getDefaultExport function for compatibility with non-harmony modules
__webpack_require__.n = function(module) {
var getter = module && module.__esModule ?
function getDefault() { return module['default']; } :
function getModuleExports() { return module; };
__webpack_require__.d(getter, 'a', getter);
return getter;
};
// Object.prototype.hasOwnProperty.call
__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
// __webpack_public_path__
__webpack_require__.p = "";
// Load entry module and return exports
return __webpack_require__(__webpack_require__.s = 1);
})
/************************************************************************/
([
/* 0 */
/***/ (function(module, exports) {
function logger(msg) {
console.log('util.js: ' + msg);
}
exports.logger = logger;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
const util = __webpack_require__(0);
util.logger('test message!');
/***/ })
]);
([
/* 0 */
/***/ (function(module, exports) {
function logger(msg) {
console.log('util.js: ' + msg);
}
exports.logger = logger;
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
const util = __webpack_require__(0);
util.logger('test message!');
/***/ })
]);
module.exports ={
entry: "./index.js",
output: {
path: __dirname + "/dist",
filename: "bundle.js",
library: 'webpack' //*
},
optimization: {
minimize: false
}
}
util.js
function logger(msg) {
console.log('util.js: ' + msg);
}
exports.logger = logger;
index.js
const util = require('./util.js');
util.logger('test message!');
exports.logger = util.logger; //*
<!DOCTYPE>
<html>
<body>
<script src="dist/bundle.js"></script>
<script>
webpack.logger('index.html');//*
</script>
</body>
</html>
>webpack
Hash: bb56f76f21d37cb07dec
Version: webpack 4.0.1
Time: 207ms
Built at: 3/2/2018 1:59:39 PM
Asset Size Chunks Chunk Names
bundle.js 2.89 KiB 0 [emitted] main
Entrypoint main = bundle.js
[0] ./util.js 90 bytes {0} [built]
[1] ./index.js 102 bytes {0} [built]
util.js: test message!
util.js: index.html
var webpack = //*** добавилась внешняя переменная
(function(modules) {
// The module cache
var installedModules = {};
// The require function
function __webpack_require__(moduleId) {
// Check if module is in cache
if(installedModules[moduleId])
return installedModules[moduleId].exports;
//...................................................
module.exports ={
context: __dirname,
entry: {
index: './index',
about: './about'
},
output: {
publicPath: '/dist',
filename: "[name].js",
library: '[name]'
},
optimization: {
minimize: false
}
}
Позволяет автоматически пересобирать приложение и запускать задачи при обнаружении изменений
module.exports ={
context: __dirname,
entry: {
index: './index'
},
output: {
publicPath: '/dist',
filename: "[name].js"
},
watch: true,
watchOptions :{//не обязательные свойства
aggregateTimeout: 300,//мс
ignored: './node_modules/',
poll: 1000//мс
},
optimization: {
minimize: false
}
}
До включения devtool
После
module.exports ={
context: __dirname,
entry: {
index: './index'
},
output: {
publicPath: '/dist',
filename: "bundle.js"
},
watch: true,
devtool: 'source-map',
optimization: {
minimize: false,
}
}
>npm install babel-loader babel-core babel-preset-es2015
babel-plugin-transform-runtime webpack --save-dev
// или
>npm install webpack --save-dev
>npm install babel-loader --save-dev
>npm install babel-core --save-dev
>npm install babel-plugin-transform-runtime --save-dev
>npm install babel-preset-es2015 --save-dev
├── index.html
├── index.js
├── util.js
├── package.json
└── webpack.config.js
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist',
library: 'webpack'
},
devtool: 'source-map',
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
}]
}
}
util.js
export default function logger(msg) {
console.log('util.js: ' + msg);
}
index.js
import {logger} from './util';
logger('test message!');
export {logger};
index.html
<!DOCTYPE>
<html>
<body>
<script src="dist/bundle.js"></script>
<script>
webpack.logger('index.html');
</script>
</body>
</html>
Hash: 353c157e6aec3bb683bb
Version: webpack 4.0.1
Time: 1339ms
Built at: 3/3/2018 12:33:20 PM
Asset Size Chunks Chunk Names
bundle.js 864 bytes 0 [emitted] index
bundle.js.map 3.46 KiB 0 [emitted] index
Entrypoint index = bundle.js bundle.js.map
[0] ./util.js 168 bytes {0} [built]
[1] ./index.js 208 bytes {0} [built]
util.js: test message!
util.js: index.html
/* 0 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.default = logger;
function logger(msg) {
console.log('util.js: ' + msg);
}
/***/ }),
/* 1 */
/***/ (function(module, exports, __webpack_require__) {
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports.logger = undefined;
var _util = __webpack_require__(0);
(0, _util.logger)('test message!');
exports.logger = _util.logger;
/***/ })
/******/ ]);
npm i uglifyjs-webpack-plugin --save-dev
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
publicPath: '/dist',
filename: "bundle.js"
},
watch: true,
plugins: [
new UglifyJsPlugin({
cache: true,
exclude: /\/node_modules/,
uglifyOptions: {
ecma: 8,
warnings: false,
parse: {},
compress: {
warnings: false,
drop_debugger: true,
unsafe: false,
drop_console: true
},
output: {
comments: false,
beautify: false
}
}
})
]
}
const webpack = require('webpack');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
publicPath: '/dist',
filename: "bundle.js"
},
watch: true,
plugins: [
new webpack.DefinePlugin({
DEBUG: JSON.stringify(true)
})
]
}
const util = require('./util.js');
util.logger('test message!');
console.log(DEBUG ? "true" : "false");//*
npm i copy-webpack-plugin --save-dev
const CopyWebpackPlugin = require('copy-webpack-plugin');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
publicPath: '/dist',
filename: "bundle.js"
},
watch: true,
plugins: [
new CopyWebpackPlugin([
{ from: 'index.html', to: 'html/' },//dist/html
{ from: '**/*.txt', to: 'txt/'}//dist/txt
])
]
}
>npm i clean-webpack-plugin --save-dev
const CleanWebpackPlugin = require('clean-webpack-plugin');
const pathsToClean = [
'dist',
'build'
];
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
plugins: [
new CleanWebpackPlugin(pathsToClean)
]
}
npm install --save-dev html-webpack-plugin
var HtmlWebpackPlugin = require('html-webpack-plugin');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
plugins: [
new HtmlWebpackPlugin({
title: 'test app'
}),
]
}
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>test app</title>
</head>
<body>
<script type="text/javascript" src="bundle.js"></script></body>
</html>
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const templatePath = path.join(__dirname, 'templates', 'index.html');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
plugins: [
new HtmlWebpackPlugin({
template: templatePath
}),
]
}
new HtmlWebpackPlugin({
minify:{
removeAttributeQuotes: true,
collapseWhitespace: true,
html5: true,
minifyCSS: false,
removeComments: true,
removeEmptyAttributes: true
}
}),
plugins: [
new HtmlWebpackPlugin(), //index.html
new HtmlWebpackPlugin({ //test.html
filename: 'test.html',
template: 'src/assets/test.html'
})
]
style.css
body{
background: red;
}
index.js
import style from './style.css';
import {logger} from './util';
logger('test message!');
ERROR in ./style.css
Module parse failed: Unexpected token (1:4)
You may need an appropriate loader to handle this file type.
| body{
| background: red;
| }
@ ./index.js 3:13-35
npm install style-loader css-loader postcss-loader
postcss-smart-import --save-dev
или
npm install style-loader --save-dev
npm install css-loader --save-dev
npm install postcss-loader --save-dev
npm install postcss-smart-import --save-dev
module.exports = {
plugins: [
require('postcss-smart-import')({ /* ...options */ }),
require('autoprefixer')({
cascade: false,
browsers: ['last 2 versions', '> 1%']
})
]
}
//........................................................
module: {
rules: [{
test: /\.js$/,
exclude: /(node_modules)/,
loader: 'babel-loader',
query: {
presets: ['es2015']
}
},
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader?importLoaders=1&sourceMap',
'postcss-loader'
]
}
]
},
//........................................................
Hash: c7d1247fe4e9733684b3
Version: webpack 4.0.1
Time: 2242ms
Built at: 3/3/2018 12:47:03 PM
Asset Size Chunks Chunk Names
bundle.js 19.1 KiB 0 [emitted] index
bundle.js.map 24 KiB 0 [emitted] index
Entrypoint index = bundle.js bundle.js.map
[0] ./util.js 168 bytes {0} [built]
[4] ./node_modules/css-loader?importLoaders=1&sourceMap!./node_modules/postcss-loader/lib!./style.css 396 bytes {0} [built]
[5] ./style.css 1.25 KiB {0} [built]
[6] ./index.js 264 bytes {0} [built]
+ 3 hidden modules
/* 4 */
/***/ (function(module, exports, __webpack_require__) {
exports = module.exports = __webpack_require__(3)(true);
// imports
// module
exports.push([module.i, "body{\r\n background: red;\r\n}", "", {"version":3,"sources":["C:/Users/HP/Desktop/webpack/style.css"],"names":[],"mappings":"AAAA;IACI,gBAAgB;CACnB","file":"style.css","sourcesContent":["body{\r\n background: red;\r\n}"],"sourceRoot":""}]);
// exports
/***/ }),
style.css
body{
background: red;
background-image: url('background.png');
}
index.js
import style from './style.css';
import {logger} from './util';
logger('test message!');
//при условии, что style-loader и css-loader установлены
ERROR in ./background.png
Module parse failed: Unexpected character '�' (1:0)
You may need an appropriate loader to handle this file type.
(Source code omitted for this binary file)
@ ./node_modules/css-loader?importLoaders=1&sourceMap!./node_modules/postcss-loader/lib!./style.css 7:96-123
@ ./style.css
@ ./index.js
>npm install file-loader image-webpack-loader --save-dev
//или
>npm install file-loader --save-dev
>npm install image-webpack-loader --save-dev
//........................................
module: {
rules: [
{
test: /\.css$/,
loaders: [
'style-loader',
'css-loader?importLoaders=1&sourceMap',
'postcss-loader'
]
},
{
test: /\.(gif|png|jpe?g|svg)$/i,
use: [
'file-loader',
//'file-loader?name=[name].[ext]',
{
loader: 'image-webpack-loader',
options: {
bypassOnDebug: true,
mozjpeg: {
progressive: true,
quality: 65
},
optipng: {
enabled: false,
optimizationLevel: 5
}
},
},
],
}
]
},
//........................................
/* 3 */
/***/ (function(module, exports, __webpack_require__) {
module.exports = __webpack_require__.p + "69070e565786768e1dcf6b933da514b2.png";
/***/ }),
/* 6 */
/***/ (function(module, exports, __webpack_require__) {
var escape = __webpack_require__(5);
exports = module.exports = __webpack_require__(4)(true);
// imports
// module
exports.push([module.i, "body{\r\n background: red;\r\n background-image: url(" + escape(__webpack_require__(3)) + ");\r\n}", "", {"version":3,"sources":["C:/Users/HP/Desktop/webpack/style.css"],"names":[],"mappings":"AAAA;IACI,gBAAgB;IAChB,gDAAwC;CAC3C","file":"style.css","sourcesContent":["body{\r\n background: red;\r\n background-image: url('background.png');\r\n}"],"sourceRoot":""}]);
// exports
/***/ }),
>npm install webpack-cli -g
>npm install webpack-dev-server -g
>npm install webpack-dev-server --save-dev
const path = require('path');
module.exports = {
context: __dirname,
entry: { index: './index' },
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
devServer: {
contentBase: path.resolve(__dirname, 'dist'),
compress: false,
port: 9000,
historyApiFallback: true,
hot: false,
inline: true,
stats: 'errors-only',
host: process.env.HOST,
}
}
//режим errors-only
>webpack-dev-server
i 「wds」: Project is running at http://localhost:9000/
i 「wds」: webpack output is served from /
i 「wds」: Content not from webpack is served from C:\Users\HP\Desktop\webpack\dist
i 「wds」: 404s will fallback to /index.html
‼ 「wdm」:
i 「wdm」: Compiled with warnings.
"scripts": {
"start": "webpack-dev-server"
}
>npm run start
{
"name": "webpack-test",
"version": "1.0.0",
"main": "index.js",
"scripts": {
"start": "webpack-dev-server"
},
"license": "ISC",
"devDependencies": {
"webpack": "^4.0.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0"
}
}
Позволяет применять изменения (обновлять, добавлять, удалять модули) без полной перезагрузки приложения
Схема работы
DEVELOPMENT ONLY
WITH webpack-dev-server
>npm install webpack-cli -g
>npm install webpack-dev-server --save-dev
>webpack-dev-server
const webpack = require('webpack');
module.exports = {
context: __dirname,
entry: {
index: './index'
},
output: {
filename: 'bundle.js',
path: __dirname + '/dist'
},
watch: true,
devServer: {
contentBase: '/dist',
hot: true
},
plugins: [
new webpack.HotModuleReplacementPlugin()
]
}
{
"name": "todo-mvc",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"build": "cross-env DEBUG=false webpack --config webpack.prod.js",
"start": "cross-env DEBUG=true webpack-dev-server --open --config webpack.dev.js",
"lint": "eslint . --ext .js --ext .jsx"
},
"author": "Maksim Hladki",
"license": "ISC",
"devDependencies": {
"autobind-decorator": "^2.1.0",
"babel-core": "^6.26.0",
"babel-eslint": "^8.2.1",
"babel-loader": "^7.1.2",
"babel-plugin-array-includes": "^2.0.3",
"babel-plugin-transform-decorators-legacy": "^1.3.4",
"babel-plugin-transform-object-assign": "^6.22.0",
"babel-plugin-transform-object-rest-spread": "^6.26.0",
"babel-preset-es2015": "^6.24.1",
"babel-preset-react": "^6.24.1",
"classnames": "^2.2.5",
"clean-webpack-plugin": "^0.1.17",
"cross-env": "^5.1.3",
"css-loader": "^0.28.7",
"eslint": "^4.15.0",
"eslint-loader": "^1.9.0",
"eslint-plugin-react": "^7.5.1",
"html-webpack-plugin": "^3.0.4",
"style-loader": "^0.19.0",
"uuid": "^3.1.0",
"webpack": "^4.0.1",
"webpack-cli": "^2.0.10",
"webpack-dev-server": "^3.1.0",
"webpack-merge": "^4.1.1"
},
"dependencies": {
"keycode-js": "^1.0.0",
"normalize.css": "^7.0.0",
"prop-types": "^15.6.0",
"react": "^16.1.1",
"react-dom": "^16.1.1",
"react-redux": "^5.0.6",
"redux": "^3.7.2",
"redux-actions": "^2.2.1",
"redux-define": "^1.1.1",
"redux-localstorage": "^0.4.1",
"redux-logger": "^3.0.6",
"todomvc-app-css": "^2.1.0"
}
}
const path = require('path'),
webpack = require('webpack'),
CleanWebpackPlugin = require('clean-webpack-plugin'),
HtmlWebpackPlugin = require('html-webpack-plugin');
const baseDir = 'src';
const PATH = {
app: path.join(__dirname, baseDir),
template: path.join(__dirname, baseDir, 'templates', 'index.html'),
build: path.join(__dirname, 'build')
};
const DEBUG = JSON.parse(process.env.DEBUG || 'false');
const devFlagPlugin = new webpack.DefinePlugin({
DEBUG: JSON.stringify(DEBUG)
});
const config = {
entry: {
app: PATH.app
},
output: {
path: PATH.build,
filename: '[name].bundle.js'
},
module: {
rules: [{
test: /\.css$/,
use: [
{
loader: 'style-loader',
},
{
loader: 'css-loader',
options: {
minimize: !DEBUG,
sourceMap: DEBUG
}
}]
},
{
test: /\.jsx?$/,
include: PATH.app,
use: [{
loader: 'babel-loader',
options: {
cacheDirectory: true
}
}]
},
{
test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [{
loader: 'url-loader',
options: {
limit: 10000,
mimetype: 'application/font-woff',
name: '[name].[ext]',
outputPath: PATH.font,
}
}]
},
{
test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
use: [{
loader: 'file-loader',
options: {
name: '[name].[ext]',
outputPath: PATH.font
}
}]
}
]
},
plugins: [
new CleanWebpackPlugin([PATH.build]),
new HtmlWebpackPlugin({
template: PATH.template,
minify: DEBUG ? false : {
removeAttributeQuotes: true,
collapseWhitespace: true,
html5: true,
minifyCSS: false,
removeComments: true,
removeEmptyAttributes: true,
}
}),
devFlagPlugin
]
};
module.exports = {
config,
path: PATH
};
const webpack = require('webpack'),
merge = require('webpack-merge'),
common = require('./webpack.common.js');
const PATH = common.path,
config = common.config;
module.exports = merge(config, {
module: {
rules: [
{
enforce: 'pre',
test: /\.js$/,
include: PATH.app,
loader: 'eslint-loader',
options: {}
},
],
},
devtool: 'eval-source-map',
devServer: {
contentBase: PATH.build,
compress: false,
port: 9000,
historyApiFallback: true,
hot: true,
inline: true,
stats: 'normal',
host: process.env.HOST,
},
plugins: [
new webpack.HotModuleReplacementPlugin()
],
});
const webpack = require('webpack'),
merge = require('webpack-merge'),
UglifyJSPlugin = require('uglifyjs-webpack-plugin'),
common = require('./webpack.common.js');
const config = common.config;
module.exports = merge(config, {
plugins: [
new UglifyJSPlugin(),
new webpack.DefinePlugin({
'process.env': {
'NODE_ENV': JSON.stringify('production')
}
})
]
});
const gulp = require('gulp'),
webpack = require('webpack-stream');
gulp.task('default', function() {
return gulp.src('src/entry.js')
.pipe(webpack( require('./webpack.config.js') ))
.pipe(gulp.dest('dist/'));
});
const gulp = require('gulp'),
webpack = require('webpack-stream');
gulp.task('default', function() {
return gulp.src('src/entry.js')
.pipe(webpack({
entry: {
app: 'src/app.js',
test: 'test/test.js',
},
output: {
filename: '[name].js',
},
}))
.pipe(gulp.dest('dist/'));
});