Подтвердить что ты не робот

Могу ли я использовать webpack для генерации CSS и JS отдельно?

У меня есть:

  • Файлы JS, которые я хочу связать.
  • МЕНЬШИЕ файлы, которые я хочу скомпилировать до CSS (разрешая @imports в один комплект).

Я надеялся указать их как два отдельных входа и иметь два отдельных выхода (вероятно, через extract-text-webpack-plugin). У Webpack есть все необходимые плагины/загрузчики для компиляции, но это не похоже на разделение.

Я видел примеры людей, которым требуются файлы LESS непосредственно из JS, такие как require('./app.less');, ни по какой другой причине, кроме как сказать webpack о включении этих файлов в комплект. Это позволяет вам иметь только одну точку входа, но мне кажется, что это неправильно для меня - зачем мне требовать МЕНЬШЕ в моем JS, когда это не имеет никакого отношения к моему JS-коду?

Я попытался использовать несколько точек входа, передав как входной JS, так и основной LESS файл, но при использовании нескольких точек входа webpack генерирует пакет, который не запускает JS при загрузке - он связывает все это, но doesn Не знаю, что должно быть выполнено при запуске.

Я просто использую webpack неправильно? Должен ли я запускать отдельные экземпляры webpack для этих отдельных модулей? Должен ли я использовать webpack для активов, отличных от JS, если я не собираюсь смешивать их с JS?

4b9b3361

Ответ 1

Должен ли я использовать webpack для активов, отличных от JS, если я не собираюсь смешивать их с JS?

Может и нет. Webpack определенно js-centric, с неявным предположением, что то, что вы строите, является js-приложением. Его реализация require() позволяет рассматривать все как модуль (в том числе частичные Sass/LESS, JSON, почти все) и автоматически управляет вашим управлением зависимостями (все, что вы require в комплекте, и ничего больше).

зачем мне требовать МЕНЬШЕ в моем JS, когда это не имеет никакого отношения к моему JS-коду?

Люди делают это, потому что они определяют часть своего приложения (например, компонент React, Backbone View) с js. В этой части приложения есть CSS, который идет с ним. В зависимости от некоторого внешнего ресурса CSS, который создается отдельно, а не напрямую ссылается на модуль js, он хрупкий, сложнее работать и может привести к устареванию стилей и т.д. Webpack рекомендует вам хранить все модульные, поэтому у вас есть CSS (Sass, что бы то ни было), частично связанный с этим компонентом js, и компонент js require(), чтобы сделать зависимость понятной (вам и инструменту построения, который никогда не создает стили, которые вам не нужны).

Я не знаю, можно ли использовать webpack для объединения CSS самостоятельно (когда файлы CSS не ссылаются ни на какие js). Я уверен, что вы можете подключить что-то с помощью плагинов и т.д., Но не уверены, что это возможно из коробки. Если вы ссылаетесь на файлы CSS из js, вы можете легко связать CSS в отдельный файл с помощью модуля Extract Text, как вы говорите.

Ответ 2

Отдельный набор CSS может быть сгенерирован без использования require('main/less) в любом из ваших JS, но, как указал Брендан в первой части своего ответа, Webpack не предназначен для глобального набора CSS, чтобы идти вместе с модульной JS, однако есть несколько вариантов.

Во-первых, добавьте дополнительную точку входа для main.less, затем используйте плагин Extract Text для создания набора CSS:

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

module.exports = {
    entry: {
        home: [
            'js/common',
            'js/homepage'
        ],
        style: [
            'styles/main.less'
        ]
    },
    output: {
        path: 'dist',
        filename: "[name].min.js"
    },
    resolve: {
        extensions: ["", ".js"]
    },
    module: {
        loaders: [{
            test: /\.less$/,
            loader: ExtractTextPlugin.extract("style", "css", "less")
        }]
    },
    plugins: [
        new ExtractTextPlugin("[name].min.css", {
            allChunks: true
        })
    ]
};

Проблема с этим методом заключается в том, что вы также генерируете нежелательный JS файл, а также пакет, в этом примере: style.js, который является просто пустым модулем Webpack.

Другой вариант - добавить основной файл меньшего размера в существующую точку входа Webpack:

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

module.exports = {
    entry: {
        home: [
            'js/common',
            'js/homepage',
            'styles/main.less'
        ],
    },
    output: {
        path: 'dist',
        filename: "[name].min.js"
    },
    resolve: {
        extensions: ["", ".js"]
    },
    module: {
        loaders: [{
            test: /\.less$/,
            loader: ExtractTextPlugin.extract("style", "css", "less")
        }]
    },
    plugins: [
        new ExtractTextPlugin("[name].min.css", {
            allChunks: true
        })
    ]
};

Это идеальный вариант, если у вас есть только одна точка входа, но если у вас их больше, то ваша конфигурация Webpack будет выглядеть немного странно, так как вам придется произвольно выбирать, в какую точку входа добавить основной файл меньше.

Ответ 3

Чтобы уточнить прежний ответ bdmason - кажется, что желательной конфигурацией было бы создание JS и CSS-пакета для каждой страницы, например:

 entry: {
        Home: ["./path/to/home.js", "./path/to/home.less"],
        About: ["./path/to/about.js", "./path/to/about.less"]
    }

И затем используйте переключатель [name]:

output: {
        path: "path/to/generated/bundles",
        filename: "[name].js"
    },
plugins: new ExtractTextPlugin("[name].css")

Полная конфигурация - с некоторыми дополнениями, не связанными с вопросом (мы фактически используем SASS вместо LESS):

var ExtractTextPlugin = require("extract-text-webpack-plugin");
var debug = process.env.NODE_ENV !== "production";
var webpack = require('webpack');
require('babel-polyfill');

module.exports = [{
    devtool: debug ? "inline-sourcemap" : null,
    entry: {
        Home: ['babel-polyfill', "./home.js","path/to/HomeRootStyle.scss"],
        SearchResults: ['babel-polyfill', "./searchResults.js","path/to/SearchResultsRootStyle.scss"]
    },
    module: {
        loaders: [
            {
                test: /\.jsx?$/,
                exclude: /(node_modules|bower_components)/,
                loader: 'babel-loader',
                query: {
                    presets: ['react', 'es2015'],
                    plugins: ['react-html-attrs', 'transform-class-properties', 'transform-decorators-legacy']
                }
            },
            {
                test: /\.scss$/,
                loader: ExtractTextPlugin.extract("style-loader","css-raw-loader!sass-loader")
            }
        ]
    },
    output: {
        path: "./res/generated",
        filename: "[name].js"
    },
    plugins: debug ? [new ExtractTextPlugin("[name].css")] : [
        new ExtractTextPlugin("[name].css"),
        new webpack.DefinePlugin({
            'process.env':{
                'NODE_ENV': JSON.stringify('production')
            }
        }),
        new webpack.optimize.UglifyJsPlugin({
            compress:{
                warnings: true
            }
        })
    ]
}
];

Ответ 4

Да, это возможно, но, как и другие, вам понадобятся дополнительные пакеты (см. DevDependencies в пакете.json). вот пример кода, который я использовал для компиляции моего загрузочного SCSS → CSS и Bootstrap JS → JS.

webpack.config.js:

module.exports = {
    mode: process.env.NODE_ENV === 'production' ? 'production' : 'development',
    entry: ['./src/app.js', './src/scss/app.scss'],
    output: {
    path: path.resolve(__dirname, 'lib/modules/theme/public'),
    filename: 'js/bootstrap.js'
    },
    module: {
        rules: [
            {
                test: /\.scss$/,
                use: [
                    {
                        loader: 'file-loader',
                        options: {
                            name: 'css/bootstrap.css',
                        }
                    },
                    {
                        loader: 'extract-loader'
                    },
                    {
                        loader: 'css-loader?-url'
                    },
                    {
                        loader: 'postcss-loader'
                    },
                    {
                        loader: 'sass-loader'
                    }
                ]
            }
        ]
    }
};

дополнительный файл postcss.config.js:

module.exports = {
    plugins: {
        'autoprefixer': {}
    }
}

package.json:

{
  "main": "app.js",
  "scripts": {
    "build": "webpack",
    "start": "node app.js"
  },
  "author": "P'unk Avenue",
  "license": "MIT",
  "dependencies": {
    "bootstrap": "^4.1.3",
  },
  "devDependencies": {
    "autoprefixer": "^9.3.1",
    "css-loader": "^1.0.1",
    "exports-loader": "^0.7.0",
    "extract-loader": "^3.1.0",
    "file-loader": "^2.0.0",
    "node-sass": "^4.10.0",
    "popper.js": "^1.14.6",
    "postcss-cli": "^6.0.1",
    "postcss-loader": "^3.0.0",
    "sass-loader": "^7.1.0",
    "style-loader": "^0.23.1",
    "webpack": "^4.26.1",
    "webpack-cli": "^3.1.2"
  }
}

См. Учебник здесь: https://florianbrinkmann.com/en/4240/sass-webpack

Ответ 5

Вы также можете поставить свои инструкции "Меньше необходимости" в свой JS файл записи:

в body.js

// CSS
require('css/_variable.scss')
require('css/_npm.scss')
require('css/_library.scss')
require('css/_lib.scss')

Затем в webpack

  entry: {
    body: [
      Path.join(__dirname, '/source/assets/javascripts/_body.js')
    ]
  },

const extractSass = new ExtractTextPlugin({
  filename: 'assets/stylesheets/all.bundle.css',
  disable: process.env.NODE_ENV === 'development',
  allChunks: true
})