Javascript-форум (https://javascript.ru/forum/)
-   Сборка проекта, утилиты (https://javascript.ru/forum/server-tools/)
-   -   Миграция на Webpack 2 c Gulp (https://javascript.ru/forum/server-tools/67197-migraciya-na-webpack-2-c-gulp.html)

yakutoc 03.02.2017 08:09

Миграция на Webpack 2 c Gulp
 
Доброго времени суток, коллеги нужны ваши советы и помощь
Суть вопроса – переезд с Gulp на Webpack 2.
Небольшое лирическое отступление. Мы используем Gulp для сборки простых сайтов.
Из js в основном различные слайдеры, jquery и различная мелочевка типа popup-ов да валидации форм.
В работе с css у нас SASS(заменим на PostCSS + CSSNext).
Причина, по которой мы затеяли переезд на Webpack 2 это, использование, в ближайших проектаx vue.js.
Типичная структура наших проектов:
src/projectName/component/header/ header.html & header.scss
src/projectName/html/index.html || pageName.html
src/projectName/fonts
src/projectName/img
src/sass/main.scss
src/js/main.js
src/vendor/jquery


Gulp все это дело собирает в папку билд, стили импортятся в один mai.css.
Js собственно тоже в один файл.
И входе миграции, возникло куча вопросов. А стоит ли игра свеч, подходит ли webpack 2 для простых сайтов, без сложных js зависимостей. Можно ли реализовать на webpackе, то что мы делаем gulp-oм?
Очень нужна ваша помощь!

nerv_ 03.02.2017 10:13

Цитата:

Сообщение от yakutoc
подходит ли webpack 2 для простых сайтов, без сложных js зависимостей

webpack 1 подходил, webpack 2, думаю, тоже будет подходить
Цитата:

Сообщение от yakutoc
Можно ли реализовать на webpackе, то что мы делаем gulp-oм?

конечно
Цитата:

Сообщение от yakutoc
Причина, по которой мы затеяли переезд на Webpack 2 это, использование, в ближайших проектаx vue.js.

вебпак тут не обязательен. Можно дедовским спобосом скрипты/шабоны подключать.

---

Я могу примерно предположить с чем у вас возникнет проблема: вебпак оперирует модулями, галп файлами. Это надо понимать и принимать во внимание.

yakutoc 03.02.2017 10:51

Спасибо за ответ. =)
Насчет дедовских методов, пытаемся с ними бороться и там где можно улучшить\автоматизировать стараемся внедрить лучшую практику.
И скорее всего наша\моя проблема в том, что я сейчас мыслю в рамках Gulp (собственно вы правильно это отметили).

Одну из задача я частично уже решил. Это было копирование статичных файлов типа изображений, html страниц и шрифтов в папку build с помощью https://github.com/kevlened/copy-webpack-plugin

Однако не со всем понимаю, как мне указать в конфиге правильную структуру build. И почему не генерится css файл.
Мой webpack.config.js
const webpack = require('webpack');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const path = require('path');
const ExtractTextPlugin = require ('extract-text-webpack-plugin');
const NODE_ENV = process.env.NODE_ENV || 'dev';

module.exports = {
	context: path.resolve(__dirname, './src/project'),


	entry: "./js/main.js",


	output: {
		path: path.resolve(__dirname,'build/assets/'),
		filename: "main.js",
	},

	module: {
		rules: [
			{
			
				test: /\.js$/,
				use: [{
					loader: 'babel-loader',
					options: { presets:['es2015'] },
				}]
			},

			{
				test: /\.css$/,
				loader: ExtractTextPlugin.extract({
					loader: 'css-loader?importLoaders=1!postcss-loader'
				}),
			},
		],
	},

	plugins: [
		new webpack.DefinePlugin({
			NODE_ENV: JSON.stringify(NODE_ENV)
		}),

		new ExtractTextPlugin('main.css'),

		new CopyWebpackPlugin([
			{
				from: './fonts',
				to: './fonts'
			},
			{
				from: './html',
				to: './'
			},
			{
				from: './img',
				to: './img'
			},
		])

	],
	watch: NODE_ENV == 'dev',

	watchOptions: {
		aggregateTimeout: 100
	},

	devtool: "cheap-eval-source-map",
};

if(NODE_ENV == 'prod') {
	module.exports.plugins.push(
		new webpack.optimize.UglifyJsPlugin({
			compress: {
				warnings: false,
				drop_console: true,
				unsafe: true,
			}
		})
	);
}

nerv_ 03.02.2017 14:21

говорить, что конкретно у тебя не так, я не возьмусь. Я могу привести свой конфиг с одного из проектов. Ты посмотришь, и вреоятно, сможешь сделать по аналогии.

Требования к конфиги сборки в данном конкретном проекте были следующие:
1. есть много легаси кода, который надо сбилдить
2. есть много кода, который использует глобальные объекты/переменные (jQuery, angular). Это требовалось учесть, надо чтобы этот код не сломался.
3. часть фронтэгд зависимостей установлена через bower. Требовалось при импоте пакета опдключать все содержимое этого пакета (стили,шрифты,картинки,скри пты)
4. три входных точки -- три файла на выходе
5. автоаннтотирование для ангуляра
6. сборка для продакшена

/
Код:

bower.json 
frontend/ 
httpdocs/
node_modules/
package.json
README.md
webpack.config.js

frontend/cart.js
'use strict';

import 'html5-history-api';
import 'object-traverse/object-traverse.js';
import 'jQuery-ajaxTransport-XDomainRequest';
//import 'jquery-suggestions/dist/css/suggestions.css'; // included in header
import 'jquery-suggestions/dist/js/jquery.suggestions.js';
import 'js/jquery/plugins/jquery.suggestions.wrapper.js';
import 'sugar';
import 'angular-i18n/angular-locale_ru.js';
import 'angular-touch';
import 'angular-animate';
import 'angular-resource';
import 'angular-route';
import 'angular-file-upload';
import 'angular-ui-utils/modules/mask/mask.js';
import 'angular-ui-utils/modules/scrollfix/scrollfix.js';
import 'angular-ui-utils/modules/validate/validate.js';
import 'imports?angular!js/angular/modules/angular-popup.js';
import 'imports?angular!js/angular/modules/angular-simple-tabs.js';
import 'imports?angular!js/angular/application/modules/cart/config.js';
import 'imports?angular!js/angular/application/modules/cart/bootstrap.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/filters.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/services.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/directives.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/controllers.js';


frontend/details.js
'use strict';

import 'html5-history-api';
import 'object-traverse/object-traverse.js';
import 'sugar'
import 'jQuery-ajaxTransport-XDomainRequest';
import 'angular-i18n/angular-locale_ru.js';
import 'angular-touch';
import 'angular-animate';
import 'angular-resource';
import 'angular-route';
import 'angular-file-upload';
import 'angular-ui-utils/modules/mask/mask.js';
import 'angular-ui-utils/modules/scrollfix/scrollfix.js';
import 'angular-ui-utils/modules/validate/validate.js';
import 'imports?angular!js/angular/modules/angular-popup.js';
import 'imports?angular!js/angular/modules/angular-simple-tabs.js';
import 'imports?angular!js/angular/application/modules/cart/config.js';
import 'imports?angular!js/angular/application/modules/cart/bootstrap.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/filters.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/services.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/directives.js';
import 'imports?angular!js/angular/application/modules/cart/scripts/controllers.js';


frontend/header.js
'use strict';

import 'bootstrap/dist/css/bootstrap.min.css'; // css, fonts, svg
import 'bower_components/jquery-ui/themes/base/core.css';
import 'bower_components/font-awesome/css/font-awesome.css'; // css, fonts
import 'bower_components/OwlCarousel/owl-carousel/owl.carousel.css';
import 'css/highslide.css';
import 'jquery-suggestions/dist/css/suggestions.css'; // Do not move it from here!

import 'recursive-iterator';
import 'jquery';
import 'jquery-ui';
import 'jqueryui-touch-punch';
import 'chosen'; // js, css, images
import 'jquery-form';
import 'fotorama'; // js, css
import 'jquery.maskedinput';
import 'magnific-popup'; // js, css
import 'swiper'; // js, css
import 'sticky';
import 'bootstrap/js/tooltip.js';
import 'bootstrap/js/popover.js';
import 'nanoscroller'; // js, css
import 'OwlCarousel/owl-carousel/owl.carousel.js';
import 'imports?jQuery=jquery!js/jquery/jquery-simple-app.min.js';
import 'angular';
import 'imports?angular!js/angular/application/common/config.js';
import 'imports?angular!js/angular/application/common/directives.js';
import 'imports?angular!js/angular/application/common/functions.js';
import 'imports?angular!js/angular/application/common/services.js';
 import 'js/highslide.js';


Код:

httpdocs/bower_components/angular/
httpdocs/bower_components/angular-animate/
httpdocs/bower_components/angular-file-upload/
httpdocs/bower_components/angular-i18n/
httpdocs/bower_components/angular-resource/
httpdocs/bower_components/angular-route/
httpdocs/bower_components/angular-touch/
httpdocs/bower_components/angular-ui-utils/
httpdocs/bower_components/bootstrap/
httpdocs/bower_components/chosen/
httpdocs/bower_components/circletype.js/
httpdocs/bower_components/es5-shim/
httpdocs/bower_components/font-awesome/
httpdocs/bower_components/fotorama/
httpdocs/bower_components/html5-history-api/
httpdocs/bower_components/idangerous-swiper/
httpdocs/bower_components/jquery/
httpdocs/bower_components/jQuery-ajaxTransport-XDomainRequest/
httpdocs/bower_components/jquery.cookie/
httpdocs/bower_components/jquery-form/
httpdocs/bower_components/jquery.maskedinput/
httpdocs/bower_components/jquery-suggestions/
httpdocs/bower_components/jquery-ui/
httpdocs/bower_components/jqueryui-touch-punch/
httpdocs/bower_components/lesshat/
httpdocs/bower_components/letteringjs/
httpdocs/bower_components/magnific-popup/
httpdocs/bower_components/nanoscroller/
httpdocs/bower_components/object-traverse/
httpdocs/bower_components/OwlCarousel/
httpdocs/bower_components/popover/
httpdocs/bower_components/recursive-iterator/
httpdocs/bower_components/sticky/
httpdocs/bower_components/sugar/
httpdocs/bower_components/swiper/

bower.json
{
  "name": "project-name",
  "dependencies": {
    "angular": "1.2.9",
    "angular-animate": "1.2.9",
    "angular-i18n": "1.2.9",
    "angular-resource": "1.2.9",
    "angular-route": "1.2.9",
    "angular-touch": "1.2.9",
    "angular-ui-utils": "0.0.3",
    "angular-file-upload": "0.3.1",
    "bootstrap": "~3.3.0",
    "circletype.js": "latest",
    "chosen": "~1.5.1",
    "fotorama": "~4.6.0",
    "font-awesome": "~4.5.0",
    "idangerous-swiper": "~3.3.1",
    "jquery": "~1.11.0",
    "jquery-form": "~3.46.0",
    "jQuery-ajaxTransport-XDomainRequest": "~1.0.4",
    "jquery.maskedinput": "~1.4.1",
    "jquery-ui": "~1.11.4",
    "jquery.cookie": "latest",
    "jqueryui-touch-punch": "latest",
    "jquery-suggestions": "https://github.com/hflabs/suggestions-jquery.git#15.1",
    "html5-history-api": "~4.2.7",
    "lesshat": "~3.0.2",
    "magnific-popup": "~1.1.0",
    "nanoscroller": "~0.8.7",
    "object-traverse": "~0.1.1",
    "OwlCarousel": "~1.3.2",
    "popover": "latest",
    "recursive-iterator": "^1.2.0",
    "sticky": "~1.0.3",
    "sugar": "~1.4.1",
    "swiper": "~3.3.0"
  }
}


package.json
{
  "scripts": {
    "bundle": "./node_modules/.bin/webpack"
  },
  "engines": {
    "node": ">=4.0.0"
  },
  "devDependencies": {
    "babel-core": "6.8.0",
    "babel-loader": "6.2.4",
    "babel-preset-es2015": "6.6.0",
    "bower-webpack-plugin": "0.1.9",
    "css-loader": "0.23.1",
    "exports-loader": "0.6.3",
    "expose-loader": "0.7.1",
    "extract-text-webpack-plugin": "1.0.1",
    "imports-loader": "0.6.5",
    "file-loader": "0.8.5",
    "ng-annotate-loader": "0.1.0",
    "raw-loader": "0.5.1",
    "style-loader": "0.13.1",
    "url-loader": "0.5.7",
    "webpack": "1.12.15"
  }
}


webpack.config.js
'use strict';

let path = require('path');
let webpack = require('webpack');
let BowerWebpackPlugin = require('bower-webpack-plugin');
let ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
  context: path.join(__dirname, 'frontend'),
  entry: {
    header: './header',
    details: './details',
    cart: './cart'
  },
  module: {
    loaders: [
      {
        test: /\.css$/,
        loader: ExtractTextPlugin.extract('style', 'css')
      },
      {
        test: /\.(eot|png|svg|ttf|woff|woff2)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
        loader: 'url?name=[name].[ext]&limit=4096'
      },
      {
        test: /\.js$/,
        loader: 'babel',
        exclude: /bower_components/
      },
      {
        test: /\/highslide\.js$/,
        loader: 'expose?hs'
      },
      {
        test: /\/jquery\.js$/,
        loader: 'expose?$!expose?jQuery'
      },
      {
        test: /\/angular\.js$/,
        loader: 'expose?angular!exports?angular'
      },
      {
        test: /\/js\/angular\/[-.\/\w]+\.js$/,
        loader: 'ng-annotate'
      }
    ]
  },
  output: {
    path: path.join(__dirname, 'httpdocs/dist'),
    publicPath: '/dist/',
    filename: '[name].js'
  },
  resolve: {
    root: [
      path.resolve(__dirname, 'httpdocs'),
      path.resolve(__dirname, 'httpdocs/bower_components')
    ]
  },
  plugins: [
    new webpack.NoErrorsPlugin(),
    new BowerWebpackPlugin({
      excludes: /.*\.less/
    }),
    new ExtractTextPlugin('styles.css'),
    new webpack.optimize.CommonsChunkPlugin({
      name: 'common'
    }),
    new webpack.optimize.UglifyJsPlugin({
      compress: {
        warnings: false
      }
    })
  ]
};



Шрифты, стили, картинки вебпак сам переносит при таком конфиге.

destus 03.02.2017 15:16

Цитата:

И почему не генерится css файл.
В вебпак2 поменяли конфигирацию лоадеров. То есть ты не можешь писать так css-loader?importLoaders=1. Ты должен писать имя лоадера без query string, а query string выносить в options. https://webpack.js.org/configuration/module/#rule-use


Часовой пояс GMT +3, время: 03:22.