Страницы

Поиск по вопросам

Показаны сообщения с ярлыком webpack. Показать все сообщения
Показаны сообщения с ярлыком webpack. Показать все сообщения

пятница, 13 марта 2020 г.

node-sass не устанавливается

#nodejs #sass #webpack


Несмотря на все ухищрения не устанавливается node-sass. sass-loader для webpack установился
нормально (есть в package.json), а модуль node-sass устанавливается (видно появляется
соответствующая папка в  node-modules, IDE Sublime Text), потом выдается ошибка и папка
исчезает.

Ошибка такая 

failed at the node-sass@3.4.2 postinstall
node scripts/build.js

Exit status 3221225477


Я все перепробовала: создавала карту в webpack.config.js

{
  test: /\.scss$/,
  loader: 'style!css!sass?sourceMap'
}


В loader.js заменила строчку 

if(map && typeof map !== "string") {
    map = JSON.stringify(map);
    }


Ничего не работает! Или на windows XP в принципе не устанавливается этот модуль (
хотя все остальные модули справно работают)?
    


Ответы

Ответ 1



Вот и нашла ответ на свой вопрос. На XP есть проблема со входом в библиотеку msvcrt.dll для Ruby. Хотя похожие проблемы с установкой node-sass есть и на 10 версии OS. На старых версиях проблема решается установкой своей среды разработки. Подробности здесь: https://github.com/oneclick/rubyinstaller/issues/239 https://github.com/oneclick/rubyinstaller/wiki/Development-Kit#building-the-devkit https://github.com/oneclick/rubyinstaller/

среда, 12 февраля 2020 г.

Настройка Webpack для использования import/require ES6

#javascript #webpack


Используя Webpack, как можно настроить loader, что бы получать файл через импорт
используя путь

import User from 'elements/user';


сама структура проекта имеет такой вид

elements/user/user.js


user.js нужно брать автоматически исходя из аналогичного название папки (аналог работы
файла по умолчанию index.js) То есть папка и файл должны быть одинаковы.
Если у кого-то есть хорошее решение помогите плиз.
    


Ответы

Ответ 1



Есть специальный плагин component-directory-webpack-plugin, настраивается следующим образом: Установка: npm i component-directory-webpack-plugin -S Настройка: // webpack.config.js var ComponentDirectoryPlugin = require('component-directory-webpack-plugin'); module.exports = { resolve: { plugins: [new ComponentDirectoryPlugin()] extensions: ['', '.js', '.jsx'] } };

среда, 5 февраля 2020 г.

Что означает `@` (собака) в пути файла?

#vuejs #webpack


С помощью утилиты vue-cli создал шаблон приложения под webpack.
В файле ./src/router/index.js обнаружил такую строку:

import Hello from '@/components/Hello'


Что означает @ (собака) в пути файла?
    


Ответы

Ответ 1



Смотрите в файл build\webpack.base.conf.js, это alias который ссылается на определенный путь, по умолчанию на 'path to project/src/'.

пятница, 10 января 2020 г.

Webpack. Сборка отдельных css и скриптов в общие файлы

#javascript #css #webpack #сборка


Как собрать разрозненные в проекте стили/скрипты в один файл (bundle.js/bundle.css)с
помощью webpack?

Проект содержит стили и скрипты для каждого приложения, которые лежат в отдельном
каталоге. Папка фронтенда:

├── frontend
│   ├── common
│   ├── node_modules
│   ├── app1
│   ├── app2
│   ├── app3
│   ├── ...
│   └── webpack.config.js


Папка каждого приложения имеет одинаковую структуру, но содержит разное количество
скриптов, стилей, шаблонов, который располагаются на одном уровне:

├── app
│   ├── static
│   │   └── app
│   │       ├── css
│   │       │   └── app.css
│   │       └── js
│   │           ├── app-detail.js
│   │           └── settings.js
│   └── templates
│       └── app
│           ├── app__element-detail.html
│           ├── app.html
│           ├── app__periodic-table.html
│           └── app__settings.html


Как собирать все эти файлы в один? 

Применительно к стилям - видел способ с extract-text-webpack-plugin, но во всех примерах
показыват один и тот же сценарий - одна точка входа, стили импортированы в скрипт и
из них уже собирается. 

Мне же нужно просто сделать бандл, его подключу в базовом шаблоне. 

Аналогичный вопрос можно задать и по сборке всех скриптов, только кроме своих скриптов
в сборку нужно включить скрипты нпм. 

Дайте, пожалуйста, советы

Мой конфиг вебпака https://jsfiddle.net/9qkwuru1/.

'use strict';

const NODE_ENV = process.env.NODE_ENV || 'development';
const webpack = require('webpack');

var ExtractTextPlugin = require('extract-text-webpack-plugin');

module.exports = {
    context: __dirname,
    entry: "./table/static/table/js/settings.js",
    output: {
        path: __dirname + "/common",
        filename: "bundle.js"
    },

    watch: NODE_ENV == 'development',
    watchOptions: {
        aggregateTimeout: 100
    },

    devtool: NODE_ENV == 'development' ? 'source-map' : null,

    resolve: {
        moduleDirectories: ['node_modules'],
        extension: ['', '.js', '.styl']
    },

    resolveLoader: {
        moduleDirectories: ['node_modules'],
        moduleTemplates: ['*-loader'],
        extension: ['', '.js'   ]
    },

    module: {
      loaders: [{
          test: /\.js$/,
          loader: 'babel',
          exclude: [
            /(node_modules|bower_components)/
          ],
          query: {
            presets: ['es2015']
          }
        }, {
          test: /\.jade$/,
          loader: 'jade'
      }, {
          test: /\.css$/,
          loader: ExtractTextPlugin.extract({
              fallbackLoader: "style-loader",
              loader: "css-loader"
          })
      }, {
          test: /\.styl$/,
          loader: 'style!css!autoprefixer?browsers=last 2 version!stylus?resolve url'
      }, {
          test: /\.(png|jpg|svg)/,
          loader: 'file?name=[path][name].[ext]'
      }]
    },

    plugins: [
        new webpack.NoErrorsPlugin(),
        new webpack.DefinePlugin({
            NODE_ENV: JSON.stringify(NODE_ENV)
        }),
        new webpack.ProvidePlugin({}),
        new ExtractTextPlugin({
            filename: "bundle.css"
        })
    ]
};

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

    


Ответы

Ответ 1



Мне приходилось решать такую задачу в одном из боевых проектов. Для этого я использовал функцию glob, которая собирает все файлы по маске. https://www.npmjs.com/package/glob И обертку для нее, которая позволяет задавать несколько таких масок массивом: https://www.npmjs.com/package/glob-all Она довольно простая, не смотрите что звезд не очень много. Ставим этот пакет (сам glob он вытянет зависимостью): npm install glob-all --save-dev В вебпак конфиге: var glob = require("glob-all"); После этого выдаем точкам входа результат, например так: entry: { yourAwesomeEntryPoint: glob.sync([ "./someFolder/*.js", "./anotherFolder/*.js" ]), Соответственно маски могут задаваться довольно хитро, в том числе регуляркой, подробнее в документации к пакетам. В моем случае этого хватило.

четверг, 9 января 2020 г.

Как подключать шрифты при сборке scss на webpack?

#шрифты #webpack #scss


Пользуясь гайдами, пытаюсь собрать все свои стили в одну сборку на Webpack.
Имеется главный файл, в него импортируется другой, в котором несколько правил @font-face
с путями к файлам шрифтов. При сборке Webpack выдаёт ошибку по этим путям, говорит:
нужен специальный загрузчик:


  ERROR in ./fonts/a_coppergothcaps-bold.ttf 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)


Но мне не то чтобы нужно (или нужно?) добавлять эти файлы в сборку. Мне достаточно,
если в сборке останутся эти правила, и браузер сам подключит шрифты по ссылкам в них.
Как сказать Webpack, чтобы не пытался обрабатывать эти пути, но просто вставлял их,
как есть? 
Или я неправильно вижу решение проблемы? Может, я шрифтами неправильно распоряжаюсь?

Вот такие правила в конфиге: 

module: {
        rules: [
            {
                test: /\.scss$/,
                use: ExtractTextPlugin.extract({
                    fallback: 'style-loader',
                    use: ['css-loader', 'sass-loader']
                })
            }
        ]
    },

    


Ответы

Ответ 1



Ссылка на полный конфиг Вот мой способ подключения шрифтов для SCSS: { test: /\.(eot|svg|ttf|woff|woff2)$/, use: [ { loader: 'file-loader?name=./assets/fonts/webfonts/[name].[ext]' }, { loader: 'file-loader?name=./assets/fonts/Roboto/[name].[ext]' } ] } Что бы это заработало нужно установить file-loader После этого нужно загрузить шрифты в SCSS: @font-face { font-family: 'Roboto Black'; src: url("/fonts/Roboto/Roboto-Black.ttf"); } Настройки webpack-dev-server: devServer: { contentBase: [path.resolve(__dirname, "build"), path.resolve(__dirname, "assets")], compress: true, port: 4200, historyApiFallback: true, noInfo:true } UPDATE 1 У меня описания шрифтов находятся в файле src/fonts.scss и файл src/variable.scss для хранения переменных размеров, цветов и т.п. В variable.scss импортируется fonts.scss -> @import "/fonts.scss"; и после этого в любом другом файле стилей можно импортировать variable.scss. В определении шрифтор должен указываться не относительный путь до файла, а url. Можно протестировать корректность вводимого адреса в браузере, например http://localhost:4200/fonts/Roboto/Roboto-Black.ttf, если было предложено сохранить файл значит все правильно.

Ответ 2



module: { rules: [ { test: /\.(svg|png|gif|jpg)$/, exclude: /fonts/, loader: 'file-loader', options: { name: '[name].[ext]' } }, { test: /\.(ttf|eot|woff|svg|woff2)$/, use: { loader: "file-loader", options: { name: `${PATHS.assets}css/fonts/[name].[ext]`, } } },plugins: [ new CopyWebpackPlugin([{ from: `${PATHS.source}/img`, to: `${PATHS.assets}img` }, { from: `${PATHS.source}/static`, to: '' }]) ]} Дабы избежать конфликта, я сделал так, благодарю что подняли этот вопрос, а также за данные на него ответы.

среда, 1 января 2020 г.

В чем смысл разделения js и css файлов в npm-пакетах с компонентами?

#reactjs #webpack #npm


Разрабатываем npm пакет с компонентами для react, чтобы их переиспользовать в других
проектах и на этапе создания конфигурации для билда возник данный вопрос.

Если посмотреть на аналоги semantic ui, bootstrap, material ui, то можно заметить
разные подходы:

Подход#1:

import "package-name/style.min.css" // или же тегом в 
import { Button } from "package-name";


Подход#2:

import { Button } from "package-name";


В первом варианте стили и скрипты представляют собой отдельные файлы, которые по
факту не работают друг без друга. Во втором случае Button является скомпилированным
файлом .js в котором содержатся и его стили и не нуждается в дополнительной загрузке CSS.

Есть ли какая то разница между подходами? В чем плюсы минусы каждого из них?

Спасибо
    


Ответы

Ответ 1



Отдельное подключение CSS позволяет заменить файл стилей на другой. К примеру, пользователь bootstrap может сделать вот так и заменить шрифт на всём сайте: $font-family-sans-serif: My Cool Font, $font-family-sans-serif; @import "bootstrap/scss/bootstrap.scss"; Также подключение CSS в head позволяет стилям загрузиться еще до скриптов - что полезно когда показать контент надо сразу же, а скрипты грузятся долго. В то же время, второй способ позволяет использовать независимую стилизацию для разных компонентов, при которой одни компоненты гарантированно не будут перекрывать своими стилями стили других компонентов. Смотрите технологии Styled Components, Css Modules и Shadow DOM (Web Components, Shadow Css).

пятница, 27 декабря 2019 г.

Как правильно собирать проект на Angular2?

#javascript #angularjs #gulp #angular2 #webpack


Более двух лет я писал приложения на Angular 1 - 1.5 и использовал для собрки gulp.
Сейчас я решил изучить Angular 2 и распространенный сегодня webpack. В процессе изучения
узнал о cli для генерации приложений на Angular 2 и автоматизации создания компонентов,
сервисов и т. д. Мне показалось это безумно удобным, но в то же время появилось два
вопроса. 


Означает ли использование cli, что мне не нужен ни gulp, ни webpack? Или есть смысл
каким-то образом комбинировать эти инструменты? Если да, то как это делаете вы? 
Допустим, я сгенерировал каркас приложения при помощи cli, создал какие-то компоненты,
написал некоторое кол-во кода, и тут я понимаю, что хочу использовать другой препроцессор
css, переименовать ряд компонентов и директив, создать новые модули и таким образом
изменить файловую структуру проекта. Не станет ли это проблемой? И смогу ли я после
этого продолжать использовать cli?


PS: Я понимаю, что cli работает на основе webpack, поэтому странно говорить, что
использовать cli, значит отказаться от webpack. Но где искать конфигурационный файл
webpack? Что, если я хочу автоматизировать заливку файлов по ftp, компиляцию jade или
делать что-то еще, чего нет по умолчанию в cli?
    


Ответы

Ответ 1



По первому вопросу: Если вы создали каркас проекта при помощи cli, то использовать gulp и webpack уже не нужно. Порядок сборки и развёртывания таков: Переходим в корневой каталог проекта npm install - устанавливаем пакеты ng build --prod --aot - собираем проект В папке /dist корневого каталога будет лежать собранный проект. При желании миницифицируем полученные файлы Заливаем содержимое папки /dist на веб-сервер Вуаля По второму вопросу: Для того, чтобы вытащить webpack.config, в корневом каталоге проекта, сгенерированного при помощи cli, выполните: ng eject В результате в консоли выведется сообщение о том, что извлечение проведено успешно, и что теперь для запуска проекта нужно использовать npm run build... etc а в корневом каталоге получите сгенерированный webpack.config, который можете конфигурировать как вам угодно. Следует отметить, что ng serve и прочие подобные команды использовать уже не сможете, а после извлечения в package.json добавится ряд новых пакетов, следовательно, перед запуском приложения после проведения извлечения, необходимо будет запустить npm install. Следовательно, алгоритм таков: Переходим в корневой каталог проекта ng eject Проверяем наличие webpack.config Вносим необходимые изменения npm install npm run build Вуаля :)

среда, 25 декабря 2019 г.

Не удается подключить Slick slider используя Webpack. Ошибка $(…).slick is not a function

#jquery #webpack #slickjs


Пробую подключить к проекту slick через webpack по примеру репозитария автора.  В
этом репозитории слайдер срабатывает.В моем проекте не заводиться, хотя вроде подключается
почти так же (отличие - в проекте используется gulp, webpack подключается через него). 
В чем может быть ошибка? Что стоит попробовать?

Репозиторий от автора слайдера с работающим примером
ссылка

Симптомы проблемы

jQuery скрипты без использования плагинов срабатывают корректно.
При подключении 'slick-carousel' выдает:

Uncaught TypeError: (0 , _jquery2.default)(...).slick is not a function


или (если подключить jquery в webpack глобально через ProvidePlugin)

$(...).slick is not a function.


Код app.js

import $ from 'jquery';
import 'slick-carousel';
$(".slider-wrapper").slick();


Версии установленных зависимостей

  "devDependencies": {
    "webpack": "3.4.1",
    "webpack-stream": "^4.0.0",
  },
  "dependencies": {
    "jquery": "1.11.1",
    "slick-carousel": "1.6.0"
  }


Конфиг webpack

const path = require('path'); //npm module for absolute path like  path.resolve(__dirname,
'./build')
const config = require('./gulp/config.js');
var webpack = require('webpack');


module.exports = {
    entry: './'+ config.src.jsEntryPoint,   
    output: {
        filename: 'bundle.js', 
        path: path.resolve(__dirname, './' + config.dest.js),   
    },
    // watch: true, //live-reloading
    devtool: 'source-map', 

    module: {
        rules: [
            {
                test: /\.js?$/,
                loader: "babel-loader"
            },
            {
                test: require.resolve("jquery"),
                use: [
                    {
                        loader: "expose-loader",
                        options: "jQuery"
                    },
                    {
                        loader: "expose-loader",
                        options: "$"
                    }
                ]
            }
        ]
    },
};


Конфиг подключения Webpack к Gulp

const gulp          = require('gulp');  
const webpackStream = require('webpack-stream');
const webpack       = require('webpack');
const config        = require('../config.js');

gulp.task('js-webpack', function() {
    gulp.src(config.src.jsEntryPoint) 
        .pipe(  webpackStream( require('../../webpack.config.js'), webpack ))
        .pipe(gulp.dest(config.dest.js));
});

    


Ответы

Ответ 1



Коллеги, проблема решена. Проблема была в конфликте зависимостей. Ее решило удаление lock-файла и установка node_modules заново.

воскресенье, 15 декабря 2019 г.

Как правильно импортировать модуль JavaScript

#javascript #webpack #сборка


В проекте имеется директория frontend следующей структуры:

├── common
    ├── static
           ├── css
           ├── js
                └── common.js
├── node_modules
├── package.json
├── app
    ├── static
           ├── css
           ├── js
                └── script1.js
                └── script2.js
└── webpack.config.js


Классы и некоторые методы, которые я определил в common.js, мне нужны в script1.js
и script2.js. Я их импортировал как

 import './common/static/js/common.js'
 import { Class1, Class2 } from './common/static/js/common.js'


Но при сборке webpack --display-error-details сообщает об отсутвующем модуле

ERROR in ./app/static/app/js/settings.js
Module not found: Error: Cannot resolve 'file' or 'directory' ./common/static/js/common.js
in      .../frontend/app/static/table/js resolve file

 .../frontend/app/static/table/js/common/static/js/common.js doesn't exist


То есть webpack ищет файл в том же каталоге, где располгается вызывающий скрипт,
а не каталог frontend.

Я понимаю, что могу задать инструкцию импорта вида ../../../../../../script.js, но
это выглядит не очень.

Можно сделать так, чтобы webpack искал относительно заданного мной каталога, в данном
случае frontend? 

Сейчас часть конфига с resolve выглядит так:

resolve: {
        moduleDirectories: ['node_modules'],
        extension: ['', '.js', '.styl']
},




Дополнение. Импорт прошел успешно только после того, как добавил в конфиг директорию
с импортируемым скриптом:

resolve: {
    root: [
        path.resolve('./common/static/js'),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Почему добавляется в качестве корня этот каталог и не добавляется каталог, в котором
лежит конфиг?



Ошибка исправлена - неправильно записывал импорты.  Настройки вебпака из ответа Утки

 resolve: {
    root: [
        path.resolve(__dirname),
    ],
    moduleDirectories: ['node_modules'],
    extension: ['', '.js', '.styl']
},


Поправил импорт

import { capitalizeFirstLetter, formatString } from 'common/static/js/common.js';
import { elementByClass, elementById } from 'common/static/js/common.js'

    


Ответы

Ответ 1



Для webpack 1 (то есть текущего стабильного документированного) нужно добавить root в секцию resolve: var path = require('path'); resolve: { root: [ path.resolve('yourRoot') ] }, yourRoot - расположение желаемого корня. Например текущую директорию для webpack.config.js можно взять так: path.resolve(__dirname) path - родной нодовский модуль, ставить отдельно не надо.

среда, 11 декабря 2019 г.

webpack-stream: где указать настройки при использовании другой версии webpack

#javascript #gulp #webpack #webpack2 #webpack_stream


В документации webpack-stream заявлена возможность использовать не ту версию webpack,
которая является зависимостью webpack-stream, а ту, которая установлена отдельно:


  If you would like to use a different version of webpack than the one
  this plugin uses, pass in an optional 2nd argument:


var gulp = require('gulp');
var webpack = require('webpack');
var gulpWebpack = require('webpack-stream');

gulp.task('default', function() {
  return gulp.src('src/entry.js')
    .pipe(gulpWebpack({}, webpack))
    .pipe(gulp.dest('dist/'));
});


Это привлекательно в первую очередь тем, что можно использовать последнию версию
webpack 2.x.x, а не deprecated-зависимость 1.x.x. Но где нужно прописывать настройки
webpack в данном случае? Для случаев, когда используется зависимость, примеры настроек
в документации есть (например, указание внешнего файла конфигурации или нескольких
точек входа), но для внешней версии webpack не сказано, как прописывать настройки.

Я пробовал вариант с настройками во внешнем файле. Если мы создадим webpack.config.js-файл,
то он будет проигнорирован. Webpack отработает без ошибок компиляции, но сгенерирует
файл с именем вроде ba2e257fdec0945b554e.js при следующих настройках в gulp-файле:

var  gulp = require('gulp'), 
    webpack = require('webpack'),
    webpackStream = require('webpack-stream');

gulp.task('wpstream', function() {
  return gulp.src('development/03_es6/index.js')
    .pipe(webpackStream({}, webpack))
    .pipe(gulp.dest('development/js'))
    .pipe(browserSync.reload({stream: true})); 
});


Насколько я могу сделать вывод, запуск консольной комманды gulp wpstream не приведёт
к тому же результату, что и выполнение комманды webpack. В последнем случае всё отрабатывает
корректно с учётом инструкций webpack.config.js, хотя в обоих случах выполняется та
желаемая (новая) версия webpack. 
    


Ответы

Ответ 1



когда ты конфигурируешь задачу следующим образом: gulp.task('wpstream', function() { return gulp.src('development/03_es6/index.js') .pipe(webpackStream({}, webpack)) .pipe(gulp.dest('development/js')) .pipe(browserSync.reload({stream: true})); }); В webpackStream({}, webpack) ты передаешь 2 параметра: 1 - объект конфигурации 2 - движок вебпака, который будет все обрабатывать. есть еще 3-й параметр - фукция для ручной обработки и вывода статистики и ошибок. Тебе же нужно обратить внимание на первый агрумент который ты передаешь, а это пустой объект. Если заглянуть в исходники webpack-sream, то можно увидеть, что если настройки не передаются или передается пустой объект, то webpack-sream запускает сам вебпак со своими дефолтными настройками. Поэтому существует как минимум 2 способа передать настройки: 1 - опрелить их прямо в webpackStream({здесь настройки}, webpack) 2- взять настройки из файла webpack.condig.js Во втором случае задача будет выглядеть примерно так: var gulp = require('gulp'), webpack = require('webpack'), webpackStream = require('webpack-stream'), webpackconfig = requre(./webpack.config.js); gulp.task('wpstream', function() { return gulp.src('development/03_es6/index.js') .pipe(webpackStream(webpackconfig, webpack)) .pipe(gulp.dest('development/js')) .pipe(browserSync.reload({stream: true})); });

пятница, 12 июля 2019 г.

Как подключать файлы к проекту,после сборки с помощью webpack, если в названии прописывается hash?

Задача при каждой сборки бандлов с помощью webpack, дописывать в названия бандлов со стилями и js хэш.Собственно говоря, сделать это не сложно. В конфиге надо просто прописать что-то типа:
output: { filename: '[name]-[hash:6].min.js', path: BUILD_DIR + '/js' },
new ExtractTextPlugin({ filename: "../css/style-[hash:6].min.css", disable: false, allChunks: true }),
Но возникает проблема. В проекте эти бандлы подключаются в twig и там я указываю путь и название файла. Без хеша как мы видим style.min.css и в head шаблона я пишу "assets/css/style.min.css" Теперь же webpack получается, каждый раз генерирует новые имена, например style-b826d0.min.css, добавляетв название хеш. И разумеется стили не подтягиваются. По сути надо каждый раз менять имя файла, т.к. хеш будет меняться. Как решить данную проблему, чтобы новый бандл с новым именем автоматически подтягивался в проект??


Ответ

Итак, ларчик просто открывался. в Твиге можно подборосить html-ку вот так Также надо использовать вебпаковский HtmlWebpackPlugin, указываем пути и направялем html в папку с твигом, куда мы будем его инклудить(почему-то если их арсположить отдельно, twig ругается). Ну а дальше, если пути к js и css бандлов заданы верно, то вебпак подставит бандлы с хешем в названии как надо. В моем случае я генерировал html на основе существующего html-шаблона,но можно это сделатьи без шаблона
new HtmlWebpackPlugin({ title: ' My title ', template: './templates/index.html', filename: '../../tiwg_template/index.html' }),

понедельник, 8 июля 2019 г.

как в webpack считывать все import'ы?

вот мой app.js:
import './scss/style.scss'; import './js/script-1.js'; import './js/script-2.js'; import './css/style-1.css'; import './css/style-2.css';
вот часть кода из конфига:
{ test: /\.js$/g, exclude: [/node_modules/], use: [{ loader: 'babel-loader', options: { presets: ['es2015'] } }] },{ test: /\.scss$/, use: [{ loader: "style-loader" }, { loader: "css-loader" }, { loader: "sass-loader", options: { includePaths: [path.resolve(__dirname, "./node_modules/compass-mixins/lib")] } }] }, { test: /\.css$/, use: [{ loader: "style-loader" }, { loader: "css-loader" }] }
в итоге у меня подключается только один файл стилей или только один скрипт. Пробовал изменить регулярку на /\.css/g, тогда вообще ничего не заработало. Может можно как-то более правильно сделать? Это важные самописные библиотеки.


Ответ

Ваши конфиги(те, что вы дали) абсолютно верны.
Давайте разберемся с Вашими скриптами, а именно формулировкой jquery не работает из комментариев. Видно, наличие скриптов в бандле Вы определяли их работоспособностью. Типичный код webpack точки входа:
import "./1.js"; import "./2.js";
На выходе Вам даст что-то вроде:
(function(module, exports, __webpack_require__) { // 1.js
}), (function(module, exports, __webpack_require__) { // 2.js })
В этом Вы можете убедится сами, открыв бандл. Очевидно, что переменная JQuery так или иначе объявленная внутри 1.js останется видна только там. То есть, в 2.js она уже будет недоступна, с чем Вы и столкнулись.
Почему так сделано за рамками этого вопроса, поэтому попробую дать ответ на вопрос "а что же делать теперь, если я хочу jquery и что-то еще в global scope"
В случае с общедоступными библиотеками, вроде той же самой jquery удобно использовать
new webpack.ProvidePlugin({ JQuery: 'jquery'// $: "jquery", refer to docs })
Для такого использования jquery должна быть предварительно установлена как npm пакет.
Для самописных проектов - можно оформить их как npm пакет. Пример простого оформления(надеюсь, никого не смутит, что моего авторства): https://github.com/vpotseluyko/url-get-parser
Или же воспользоваться expose-loader
Пример:
Точка входа:
require("expose-loader?varname!./main.js");
Main.js
module.exports = 'my imp string for global scope';
Где-то в inline script:
console.log(varname); // `my imp string...'(only after webpack script loaded)

среда, 12 июня 2019 г.

Webpack 3 не работает компиляция scss

const path = require('path'); const ExtractTextPlugin = require ('extract-text-webpack-plugin');
module.exports = { context: __dirname,
entry : { common: './source/js/common.js' },
output: { path: path.resolve(__dirname, './public/js'), filename: '[name].js' },
module: { rules: [ { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: [ 'css-loader', 'sass-loader' ] }) } ] },
plugins: [ new ExtractTextPlugin('common.css') ] }
Time: 133ms Asset Size Chunks Chunk Names common.js 2.53 kB 0 [emitted] common [0] ./source/js/common.js 53 bytes {0} [built]
Не генерируется сss файл. Как посмотреть что плагин вообще запускается. Может логер есть какой нибудь?


Ответ

Устанавливаем модуль:
npm i -D extract-text-webpack-plugin
Подключаем:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
Ну и код модуля вынесенный в отдельный файл:
const ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = function (paths) { return { module: { rules: [ { test: /\.scss$/, include: paths, use: ExtractTextPlugin.extract({ publicPath: '../', fallback: 'style-loader', use: ['css-loader', 'sass-loader'] }) }, { test: /\.css$/, include: paths, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) } ] }, plugins: [ new ExtractTextPlugin('./css/[name].css') ] }; };
Соедините с основным конфигом с помощью пакета "webpack-merge". Если же не хотите выносить в отдельный файл то просто подключите в webpack.config.js и вставите:
module: { rules: [ { test: /\.scss$/, use: ExtractTextPlugin.extract({ publicPath: '../', fallback: 'style-loader', use: ['css-loader', 'sass-loader'] }) }, { test: /\.css$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: 'css-loader' }) } ] }, plugins: [ new ExtractTextPlugin('./css/[name].css') ] };
Ну и не забудьте пути к вашим файлам подкорректировать.

воскресенье, 9 июня 2019 г.

Как подключать шрифты при сборке scss на webpack?

Пользуясь гайдами, пытаюсь собрать все свои стили в одну сборку на Webpack. Имеется главный файл, в него импортируется другой, в котором несколько правил @font-face с путями к файлам шрифтов. При сборке Webpack выдаёт ошибку по этим путям, говорит: нужен специальный загрузчик:
ERROR in ./fonts/a_coppergothcaps-bold.ttf 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)
Но мне не то чтобы нужно (или нужно?) добавлять эти файлы в сборку. Мне достаточно, если в сборке останутся эти правила, и браузер сам подключит шрифты по ссылкам в них. Как сказать Webpack, чтобы не пытался обрабатывать эти пути, но просто вставлял их, как есть? Или я неправильно вижу решение проблемы? Может, я шрифтами неправильно распоряжаюсь?
Вот такие правила в конфиге:
module: { rules: [ { test: /\.scss$/, use: ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader', 'sass-loader'] }) } ] },


Ответ

Ссылка на полный конфиг
Вот мой способ подключения шрифтов для SCSS:
{ test: /\.(eot|svg|ttf|woff|woff2)$/, use: [ { loader: 'file-loader?name=./assets/fonts/webfonts/[name].[ext]' }, { loader: 'file-loader?name=./assets/fonts/Roboto/[name].[ext]' } ] }

Что бы это заработало нужно установить file-loader
После этого нужно загрузить шрифты в SCSS:
@font-face { font-family: 'Roboto Black'; src: url("/fonts/Roboto/Roboto-Black.ttf"); }

Настройки webpack-dev-server:
devServer: { contentBase: [path.resolve(__dirname, "build"), path.resolve(__dirname, "assets")], compress: true, port: 4200, historyApiFallback: true, noInfo:true }

UPDATE 1
У меня описания шрифтов находятся в файле src/fonts.scss и файл src/variable.scss для хранения переменных размеров, цветов и т.п. В variable.scss импортируется fonts.scss -> @import "/fonts.scss"; и после этого в любом другом файле стилей можно импортировать variable.scss. В определении шрифтор должен указываться не относительный путь до файла, а url. Можно протестировать корректность вводимого адреса в браузере, например http://localhost:4200/fonts/Roboto/Roboto-Black.ttf, если было предложено сохранить файл значит все правильно.

среда, 20 февраля 2019 г.

Webpack. Сборка отдельных css и скриптов в общие файлы

Как собрать разрозненные в проекте стили/скрипты в один файл (bundle.js/bundle.css)с помощью webpack?
Проект содержит стили и скрипты для каждого приложения, которые лежат в отдельном каталоге. Папка фронтенда:
├── frontend │   ├── common │   ├── node_modules │   ├── app1 │   ├── app2 │   ├── app3 │   ├── ... │   └── webpack.config.js
Папка каждого приложения имеет одинаковую структуру, но содержит разное количество скриптов, стилей, шаблонов, который располагаются на одном уровне:
├── app │   ├── static │   │   └── app │   │   ├── css │   │   │   └── app.css │   │   └── js │   │   ├── app-detail.js │   │   └── settings.js │   └── templates │   └── app │   ├── app__element-detail.html │   ├── app.html │   ├── app__periodic-table.html │   └── app__settings.html
Как собирать все эти файлы в один?
Применительно к стилям - видел способ с extract-text-webpack-plugin, но во всех примерах показыват один и тот же сценарий - одна точка входа, стили импортированы в скрипт и из них уже собирается.
Мне же нужно просто сделать бандл, его подключу в базовом шаблоне.
Аналогичный вопрос можно задать и по сборке всех скриптов, только кроме своих скриптов в сборку нужно включить скрипты нпм.
Дайте, пожалуйста, советы
Мой конфиг вебпака https://jsfiddle.net/9qkwuru1/
'use strict';
const NODE_ENV = process.env.NODE_ENV || 'development'; const webpack = require('webpack');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
module.exports = { context: __dirname, entry: "./table/static/table/js/settings.js", output: { path: __dirname + "/common", filename: "bundle.js" },
watch: NODE_ENV == 'development', watchOptions: { aggregateTimeout: 100 },
devtool: NODE_ENV == 'development' ? 'source-map' : null,
resolve: { moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
resolveLoader: { moduleDirectories: ['node_modules'], moduleTemplates: ['*-loader'], extension: ['', '.js' ] },
module: { loaders: [{ test: /\.js$/, loader: 'babel', exclude: [ /(node_modules|bower_components)/ ], query: { presets: ['es2015'] } }, { test: /\.jade$/, loader: 'jade' }, { test: /\.css$/, loader: ExtractTextPlugin.extract({ fallbackLoader: "style-loader", loader: "css-loader" }) }, { test: /\.styl$/, loader: 'style!css!autoprefixer?browsers=last 2 version!stylus?resolve url' }, { test: /\.(png|jpg|svg)/, loader: 'file?name=[path][name].[ext]' }] },
plugins: [ new webpack.NoErrorsPlugin(), new webpack.DefinePlugin({ NODE_ENV: JSON.stringify(NODE_ENV) }), new webpack.ProvidePlugin({}), new ExtractTextPlugin({ filename: "bundle.css" }) ] };
if (NODE_ENV == 'production') { module.exports.plugins.push( new webpack.optimize.UglifyJsPlugin({ compress: { warnings: false, drop_console: true, unsafe: true } }) ) }


Ответ

Мне приходилось решать такую задачу в одном из боевых проектов.
Для этого я использовал функцию glob, которая собирает все файлы по маске. https://www.npmjs.com/package/glob И обертку для нее, которая позволяет задавать несколько таких масок массивом: https://www.npmjs.com/package/glob-all Она довольно простая, не смотрите что звезд не очень много.
Ставим этот пакет (сам glob он вытянет зависимостью):
npm install glob-all --save-dev
В вебпак конфиге:
var glob = require("glob-all");
После этого выдаем точкам входа результат, например так:
entry: { yourAwesomeEntryPoint: glob.sync([ "./someFolder/*.js", "./anotherFolder/*.js" ]),
Соответственно маски могут задаваться довольно хитро, в том числе регуляркой, подробнее в документации к пакетам.
В моем случае этого хватило.

четверг, 29 ноября 2018 г.

Не удается подключить Slick slider используя Webpack. Ошибка $(…).slick is not a function

Пробую подключить к проекту slick через webpack по примеру репозитария автора. В этом репозитории слайдер срабатывает.В моем проекте не заводиться, хотя вроде подключается почти так же (отличие - в проекте используется gulp, webpack подключается через него). В чем может быть ошибка? Что стоит попробовать?
Репозиторий от автора слайдера с работающим примером ссылка
Симптомы проблемы
jQuery скрипты без использования плагинов срабатывают корректно. При подключении 'slick-carousel' выдает:
Uncaught TypeError: (0 , _jquery2.default)(...).slick is not a function
или (если подключить jquery в webpack глобально через ProvidePlugin)
$(...).slick is not a function.
Код app.js
import $ from 'jquery'; import 'slick-carousel'; $(".slider-wrapper").slick();
Версии установленных зависимостей
"devDependencies": { "webpack": "3.4.1", "webpack-stream": "^4.0.0", }, "dependencies": { "jquery": "1.11.1", "slick-carousel": "1.6.0" }
Конфиг webpack
const path = require('path'); //npm module for absolute path like path.resolve(__dirname, './build') const config = require('./gulp/config.js'); var webpack = require('webpack');
module.exports = { entry: './'+ config.src.jsEntryPoint, output: { filename: 'bundle.js', path: path.resolve(__dirname, './' + config.dest.js), }, // watch: true, //live-reloading devtool: 'source-map',
module: { rules: [ { test: /\.js?$/, loader: "babel-loader" }, { test: require.resolve("jquery"), use: [ { loader: "expose-loader", options: "jQuery" }, { loader: "expose-loader", options: "$" } ] } ] }, };
Конфиг подключения Webpack к Gulp
const gulp = require('gulp'); const webpackStream = require('webpack-stream'); const webpack = require('webpack'); const config = require('../config.js');
gulp.task('js-webpack', function() { gulp.src(config.src.jsEntryPoint) .pipe( webpackStream( require('../../webpack.config.js'), webpack )) .pipe(gulp.dest(config.dest.js)); });


Ответ

Коллеги, проблема решена. Проблема была в конфликте зависимостей. Ее решило удаление lock-файла и установка node_modules заново.

понедельник, 29 октября 2018 г.

webpack-stream: где указать настройки при использовании другой версии webpack

В документации webpack-stream заявлена возможность использовать не ту версию webpack, которая является зависимостью webpack-stream, а ту, которая установлена отдельно:
If you would like to use a different version of webpack than the one this plugin uses, pass in an optional 2nd argument:
var gulp = require('gulp'); var webpack = require('webpack'); var gulpWebpack = require('webpack-stream');
gulp.task('default', function() { return gulp.src('src/entry.js') .pipe(gulpWebpack({}, webpack)) .pipe(gulp.dest('dist/')); });
Это привлекательно в первую очередь тем, что можно использовать последнию версию webpack 2.x.x, а не deprecated-зависимость 1.x.x. Но где нужно прописывать настройки webpack в данном случае? Для случаев, когда используется зависимость, примеры настроек в документации есть (например, указание внешнего файла конфигурации или нескольких точек входа), но для внешней версии webpack не сказано, как прописывать настройки.
Я пробовал вариант с настройками во внешнем файле. Если мы создадим webpack.config.js-файл, то он будет проигнорирован. Webpack отработает без ошибок компиляции, но сгенерирует файл с именем вроде ba2e257fdec0945b554e.js при следующих настройках в gulp-файле:
var gulp = require('gulp'), webpack = require('webpack'), webpackStream = require('webpack-stream');
gulp.task('wpstream', function() { return gulp.src('development/03_es6/index.js') .pipe(webpackStream({}, webpack)) .pipe(gulp.dest('development/js')) .pipe(browserSync.reload({stream: true})); });
Насколько я могу сделать вывод, запуск консольной комманды gulp wpstream не приведёт к тому же результату, что и выполнение комманды webpack. В последнем случае всё отрабатывает корректно с учётом инструкций webpack.config.js, хотя в обоих случах выполняется та желаемая (новая) версия webpack.


Ответ

когда ты конфигурируешь задачу следующим образом:
gulp.task('wpstream', function() { return gulp.src('development/03_es6/index.js') .pipe(webpackStream({}, webpack)) .pipe(gulp.dest('development/js')) .pipe(browserSync.reload({stream: true})); });
В webpackStream({}, webpack) ты передаешь 2 параметра: 1 - объект конфигурации 2 - движок вебпака, который будет все обрабатывать. есть еще 3-й параметр - фукция для ручной обработки и вывода статистики и ошибок. Тебе же нужно обратить внимание на первый агрумент который ты передаешь, а это пустой объект. Если заглянуть в исходники webpack-sream, то можно увидеть, что если настройки не передаются или передается пустой объект, то webpack-sream запускает сам вебпак со своими дефолтными настройками. Поэтому существует как минимум 2 способа передать настройки: 1 - опрелить их прямо в webpackStream({здесь настройки}, webpack) 2- взять настройки из файла webpack.condig.js
Во втором случае задача будет выглядеть примерно так:
var gulp = require('gulp'), webpack = require('webpack'), webpackStream = require('webpack-stream'), webpackconfig = requre(./webpack.config.js);
gulp.task('wpstream', function() { return gulp.src('development/03_es6/index.js') .pipe(webpackStream(webpackconfig, webpack)) .pipe(gulp.dest('development/js')) .pipe(browserSync.reload({stream: true})); });

суббота, 27 октября 2018 г.

Как правильно импортировать модуль JavaScript

В проекте имеется директория frontend следующей структуры:
├── common ├── static    ├── css    ├── js      └── common.js ├── node_modules ├── package.json ├── app ├── static    ├── css    ├── js      └── script1.js └── script2.js └── webpack.config.js
Классы и некоторые методы, которые я определил в common.js, мне нужны в script1.js и script2.js. Я их импортировал как
import './common/static/js/common.js' import { Class1, Class2 } from './common/static/js/common.js'
Но при сборке webpack --display-error-details сообщает об отсутвующем модуле
ERROR in ./app/static/app/js/settings.js Module not found: Error: Cannot resolve 'file' or 'directory' ./common/static/js/common.js in .../frontend/app/static/table/js resolve file
.../frontend/app/static/table/js/common/static/js/common.js doesn't exist
То есть webpack ищет файл в том же каталоге, где располгается вызывающий скрипт, а не каталог frontend
Я понимаю, что могу задать инструкцию импорта вида ../../../../../../script.js, но это выглядит не очень.
Можно сделать так, чтобы webpack искал относительно заданного мной каталога, в данном случае frontend?
Сейчас часть конфига с resolve выглядит так:
resolve: { moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },

Дополнение. Импорт прошел успешно только после того, как добавил в конфиг директорию с импортируемым скриптом:
resolve: { root: [ path.resolve('./common/static/js'), ], moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
Почему добавляется в качестве корня этот каталог и не добавляется каталог, в котором лежит конфиг?

Ошибка исправлена - неправильно записывал импорты. Настройки вебпака из ответа Утки
resolve: { root: [ path.resolve(__dirname), ], moduleDirectories: ['node_modules'], extension: ['', '.js', '.styl'] },
Поправил импорт
import { capitalizeFirstLetter, formatString } from 'common/static/js/common.js'; import { elementByClass, elementById } from 'common/static/js/common.js'


Ответ

Для webpack 1 (то есть текущего стабильного документированного) нужно добавить root в секцию resolve
var path = require('path');
resolve: { root: [ path.resolve('yourRoot') ] },
yourRoot - расположение желаемого корня. Например текущую директорию для webpack.config.js можно взять так: path.resolve(__dirname)
path - родной нодовский модуль, ставить отдельно не надо.