Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Compatibility with Webpack 5 #2802

Merged
merged 36 commits into from
Dec 20, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
b634d67
Major packages bump
gauravtiwari Aug 8, 2020
bcde488
Major upgrade
gauravtiwari Aug 8, 2020
b4701ed
New automatic API
gauravtiwari Aug 8, 2020
e2ea63a
Automatic rules
gauravtiwari Aug 8, 2020
1153bfb
Update configuration
gauravtiwari Aug 8, 2020
4ad3419
Remove loader installs
gauravtiwari Aug 8, 2020
3564dd5
Move plugins
gauravtiwari Aug 16, 2020
7624056
Restructure
gauravtiwari Aug 30, 2020
e81793b
Remove old confis
gauravtiwari Aug 30, 2020
bcaa218
Update packages
gauravtiwari Sep 29, 2020
b6e54c1
Remove extract_css
gauravtiwari Sep 29, 2020
c23caff
Remove unwanted rules
gauravtiwari Sep 29, 2020
4e4e779
Remove extra installers
gauravtiwari Sep 29, 2020
6346111
Cleanup deps
gauravtiwari Dec 6, 2020
bd5713c
Merge master
gauravtiwari Dec 13, 2020
16f73bc
Upgrade assets plugin and make things work
gauravtiwari Dec 13, 2020
8f0c048
Make eslint happy
gauravtiwari Dec 19, 2020
22aea22
Fix tests
gauravtiwari Dec 19, 2020
86d3b86
Remove extra deps
gauravtiwari Dec 19, 2020
a1e3e54
Merge branch 'master' into automatic-rules
gauravtiwari Dec 19, 2020
78da636
Upgrade to latest
gauravtiwari Dec 19, 2020
ac0f9f5
Update assets plugin
gauravtiwari Dec 19, 2020
4af653b
Use assets key
gauravtiwari Dec 19, 2020
09fdf0d
Use loader objectt
gauravtiwari Dec 20, 2020
33840e6
Update mini css extract plugin
gauravtiwari Dec 20, 2020
f7c9a95
Correct import
gauravtiwari Dec 20, 2020
35e6b4d
Implementation is an object
gauravtiwari Dec 20, 2020
2f08d6b
Remove file loader and use native assets
gauravtiwari Dec 20, 2020
c651b98
Use eslint prettier config
gauravtiwari Dec 20, 2020
a42deef
Cleanup rules
gauravtiwari Dec 20, 2020
2f64b8f
Delete node modules loader
gauravtiwari Dec 20, 2020
7d81bc4
Make mini data uri optional
gauravtiwari Dec 20, 2020
12ddd48
Make postcss optional
gauravtiwari Dec 20, 2020
41f5bc8
Make dev server available by default
gauravtiwari Dec 20, 2020
9cb22c6
Actually not a great idea
gauravtiwari Dec 20, 2020
3d541f3
Support Avif and webp
gauravtiwari Dec 20, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 24 additions & 29 deletions docs/css.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# CSS, Sass and SCSS


Webpacker supports importing CSS, Sass and SCSS files directly into your JavaScript files.

Importing and loading styles is a two step process:
Expand All @@ -15,7 +14,6 @@ Importing and loading styles is a two step process:

When you do `<%= stylesheet_pack_tag 'application' %>`, that's a run-time inclusion from Rails, where Rails gets the correct "asset path" to that file from webpack.


## Import global styles into your JS app

### Importing CSS as a multi-file pack (Webpacker v5)
Expand Down Expand Up @@ -60,7 +58,6 @@ Given your application installs an NPM package that provides CSS, such as `flatp
@import "flatpickr/dist/flatpickr.css"
```


### Importing CSS from JS

```sass
Expand All @@ -79,9 +76,9 @@ import React from 'react'
import helloIcon from '../hello_react/images/icon.png'
import '../hello_react/styles/hello-react'

const Hello = props => (
<div className="hello-react">
<img src={helloIcon} alt="hello-icon" />
const Hello = (props) => (
<div className='hello-react'>
<img src={helloIcon} alt='hello-icon' />
<p>Hello {props.name}!</p>
</div>
)
Expand All @@ -94,7 +91,7 @@ Given your application installs an NPM package that provides CSS, such as `flatp
```js
// app/javascript/packs/application.js

import "flatpickr/dist/flatpickr.css"
import 'flatpickr/dist/flatpickr.css'
```

## Import scoped styles into your JS app
Expand All @@ -117,9 +114,9 @@ import React from 'react'
import helloIcon from '../hello_react/images/icon.png'
import styles from '../hello_react/styles/hello-react'

const Hello = props => (
const Hello = (props) => (
<div className={styles.helloReact}>
<img src={helloIcon} alt="hello-icon" />
<img src={helloIcon} alt='hello-icon' />
<p>Hello {props.name}!</p>
</div>
)
Expand All @@ -142,7 +139,7 @@ Using CSS modules with a TypeScript application requires a few differences from
There must also be a type definition file for these styles:

```typescript
export const helloReact: string;
export const helloReact: string
```

You can then import the styles like this:
Expand All @@ -155,9 +152,9 @@ import React from 'react'
import helloIcon from '../hello_react/images/icon.png'
import * as styles from '../hello_react/styles/hello-react.module.sass'

const Hello = props => (
const Hello = (props) => (
<div className={styles.helloReact}>
<img src={helloIcon} alt="hello-icon" />
<img src={helloIcon} alt='hello-icon' />
<p>Hello {props.name}!</p>
</div>
)
Expand All @@ -180,7 +177,6 @@ Then by adding these lines to your `package.json`:

You can generate the typings for the stylesheet by running the command `yarn gen-typings` when you've finished writing CSS, or run `yarn watch-typings` to have it automatically generate them as you go.


## Link styles from your Rails views

Under the hood webpack uses
Expand All @@ -192,8 +188,6 @@ a separate `[pack_name].css` bundle so that in your view you can use the
<%= stylesheet_pack_tag 'hello_react' %>
```

Webpacker emits css files only if `extract_css` is set to true in webpacker.yml otherwise `stylesheet_pack_tag` returns nil.

## Add bootstrap

You can use Yarn to add bootstrap or any other modules available on npm:
Expand All @@ -218,7 +212,6 @@ Or in your app/javascript/packs/application.sass file:
@import '~bootstrap/dist/css/bootstrap-theme'
```


## Post-Processing CSS

Webpacker out-of-the-box provides CSS post-processing using
Expand All @@ -244,8 +237,8 @@ module.exports = {
## Using CSS with [vue-loader](https://github.com/vuejs/vue-loader)

Vue templates require loading the stylesheet in your application in
order for CSS to work. This is in addition to loading the JavaScript
file for the entry point. Loading the stylesheet will also load the
order for CSS to work. This is in addition to loading the JavaScript
file for the entry point. Loading the stylesheet will also load the
CSS for any nested components.

```erb
Expand All @@ -257,7 +250,6 @@ CSS for any nested components.

Since `Sass/libsass` does not provide url rewriting, all linked assets must be relative to the output. Add the missing url rewriting using the resolve-url-loader. Place it directly after the sass-loader in the loader chain.


```bash
yarn add resolve-url-loader
```
Expand All @@ -269,7 +261,7 @@ const { environment } = require('@rails/webpacker')
// resolve-url-loader must be used before sass-loader
environment.loaders.get('sass').use.splice(-1, 0, {
loader: 'resolve-url-loader'
});
})

module.exports = environment
```
Expand All @@ -280,13 +272,14 @@ In order to get CSS to work with typescript you have two options.
You can either use `require` to bypass typescript special `import`.

```ts
const styles = require('../hello_react/styles/hello-react');
const styles = require('../hello_react/styles/hello-react')
```

You may also use the package [typings-for-css-modules-loader](https://github.com/Jimdo/typings-for-css-modules-loader) instead of `css-loader` to automatically generate typescript `.d.ts` files in order to help resolve any css/scss styles. To do that:

```js
// app/javascript/packs/hello_react.jsx
import * as styles from '../hello_react.styles/hello-react.module.scss';
import * as styles from '../hello_react.styles/hello-react.module.scss'
```

```bash
Expand All @@ -298,11 +291,13 @@ yarn add --dev typings-for-css-modules-loader
const { environment } = require('@rails/webpacker')

// replace css-loader with typings-for-css-modules-loader
environment.loaders.get('moduleSass').use = environment.loaders.get('moduleSass').use.map((u) => {
if(u.loader == 'css-loader') {
return { ...u, loader: 'typings-for-css-modules-loader' };
} else {
return u;
}
});
environment.loaders.get('moduleSass').use = environment.loaders
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @gauravtiwari

should it be loaders.get('moduleSass').use ?

const { environment, loaders } = require('@rails/webpacker')

console.log('environment', environment)
console.log('loaders', loaders)

environment undefined
loaders [
  {
    test: [

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@pustovalov Hey, I think we need to overhaul the documentation. The class-based API is removed in 6.x

I will work on updating docs.

.get('moduleSass')
.use.map((u) => {
if (u.loader == 'css-loader') {
return { ...u, loader: 'typings-for-css-modules-loader' }
} else {
return u
}
})
```
10 changes: 3 additions & 7 deletions docs/webpack-dev-server.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# webpack-dev-server


## HTTPS

If you're using the `webpack-dev-server` in development, you can serve your packs over HTTPS
Expand All @@ -13,23 +12,21 @@ so your web browser will display a warning/exception upon accessing the page. If
in your console, simply open the link in your browser and accept the SSL exception.
Now if you refresh your Rails view everything should work as expected.


## Hot Module Replacement

Webpacker out-of-the-box supports HMR with `webpack-dev-server` and
you can toggle it by setting options in `config/webpacker.yml`:

```yaml
development:
# ...
extract_css: false
# ...
dev_server:
# ...
hmr: true
inline: true
# ...
```

`dev_server/hmr` option inside `webpacker.yml`.

Check out this guide for more information:
Expand Down Expand Up @@ -83,9 +80,8 @@ server {
## Customizing Logging

By default, the dev server will display a colored progress notification while
your code is being compiled. (Under the hood, we are using `webpack-dev-server
--progress --color`). However, this might cause issues if you don't use
`foreman` and/or try to log webpack-dev-server's output to a file. You can
your code is being compiled. (Under the hood, we are using `webpack-dev-server --progress --color`). However, this might cause issues if you don't use
`foreman` and/or try to log webpack-dev-server's output to a file. You can
disable this stylized output by adding `pretty: false` to your `dev_server`
config:

Expand Down
4 changes: 0 additions & 4 deletions lib/webpacker/configuration.rb
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,6 @@ def webpack_compile_output?
fetch(:webpack_compile_output)
end

def extract_css?
fetch(:extract_css)
end

private
def fetch(key)
data.fetch(key, defaults[key])
Expand Down
25 changes: 4 additions & 21 deletions lib/webpacker/helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,9 @@ def current_webpacker_instance
#
# Example:
#
# # When extract_css is false in webpacker.yml and the file is a css:
# <%= asset_pack_path 'calendar.css' %> # => nil
#
# # When extract_css is true in webpacker.yml or the file is not a css:
# <%= asset_pack_path 'calendar.css' %> # => "/packs/calendar-1016838bab065ae1e122.css"
def asset_pack_path(name, **options)
if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
if !stylesheet?(name)
path_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
end
end
Expand All @@ -29,13 +25,9 @@ def asset_pack_path(name, **options)
#
# Example:
#
# # When extract_css is false in webpacker.yml and the file is a css:
# <%= asset_pack_url 'calendar.css' %> # => nil
#
# # When extract_css is true in webpacker.yml or the file is not a css:
# <%= asset_pack_url 'calendar.css' %> # => "http://example.com/packs/calendar-1016838bab065ae1e122.css"
def asset_pack_url(name, **options)
if current_webpacker_instance.config.extract_css? || !stylesheet?(name)
if !stylesheet?(name)
url_to_asset(current_webpacker_instance.manifest.lookup!(name), options)
end
end
Expand Down Expand Up @@ -148,17 +140,10 @@ def preload_pack_asset(name, **options)
#
# Examples:
#
# # When extract_css is false in webpacker.yml:
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
# nil
#
# # When extract_css is true in webpacker.yml:
# <%= stylesheet_pack_tag 'calendar', 'data-turbolinks-track': 'reload' %> # =>
# <link rel="stylesheet" media="screen" href="/packs/calendar-1016838bab065ae1e122.css" data-turbolinks-track="reload" />
def stylesheet_pack_tag(*names, **options)
if current_webpacker_instance.config.extract_css?
stylesheet_link_tag(*sources_from_manifest_entries(names, type: :stylesheet), **options)
end
stylesheet_link_tag(*sources_from_manifest_entries(names, type: :stylesheet), **options)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gauravtiwari @rossta why was this removed? If one is using HMR with React, we don't want to extract the CSS. We want the CSS to come from the JS files so that it can be dynamically loaded in the browser.

end

# Creates link tags that reference the css chunks from entrypoints when using split chunks API,
Expand All @@ -183,9 +168,7 @@ def stylesheet_pack_tag(*names, **options)
# <%= stylesheet_packs_with_chunks_tag 'calendar' %>
# <%= stylesheet_packs_with_chunks_tag 'map' %>
def stylesheet_packs_with_chunks_tag(*names, **options)
if current_webpacker_instance.config.extract_css?
stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
end
stylesheet_link_tag(*sources_from_manifest_entrypoints(names, type: :stylesheet), **options)
end

private
Expand Down
6 changes: 3 additions & 3 deletions package/environments/development.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const devServer = require('../dev_server')

const { outputPath: contentBase, publicPath } = require('../config')

const devConfig = {
let devConfig = {
mode: 'development',
devtool: 'cheap-module-source-map'
}
Expand All @@ -16,15 +16,15 @@ if (
process.env.WEBPACK_DEV_SERVER !== 'undefined'
) {
if (devServer.hmr) {
merge(devConfig, {
devConfig = merge(devConfig, {
output: {
filename: '[name]-[hash].js'
},
plugins: [new webpack.HotModuleReplacementPlugin()]
})
}

merge(devConfig, {
devConfig = merge(devConfig, {
devServer: {
clientLogLevel: 'none',
compress: devServer.compress,
Expand Down
1 change: 1 addition & 0 deletions package/rules/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ const load = (name) => {
try {
return require(`./${name}`)
} catch (e) {
console.error(e)
return null
}
}
Expand Down
29 changes: 0 additions & 29 deletions package/utils/__tests__/get_style_rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,33 +33,4 @@ describe('getStyleRule', () => {

expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation))
})

test('adds mini-css-extract-plugin when extract_css is true', () => {
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const expectation = [MiniCssExtractPlugin.loader]

require('../../config').extract_css = true
const cssRule = getStyleRule(/\.(css)$/i)

expect(cssRule.use).toMatchObject(expect.arrayContaining(expectation))
})

test('adds style-loader when extract_css is true', () => {
const expectation = [{loader: 'style-loader'}]

require('../../config').extract_css = false
const cssRule = getStyleRule(/\.(css)$/i)

expect(cssRule.use).toMatchObject(expect.objectContaining(expectation))
})

test(`doesn't add mini-css-extract-plugin when extract_css is false`, () => {
const MiniCssExtractPlugin = require('mini-css-extract-plugin')
const expectation = [MiniCssExtractPlugin.loader]

require('../../config').extract_css = false
const cssRule = getStyleRule(/\.(css)$/i)

expect(cssRule.use).toMatchObject(expect.not.arrayContaining(expectation))
})
})
15 changes: 14 additions & 1 deletion package/utils/get_style_rule.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,19 @@
const devServer = require('../dev_server')

const getStyleRule = (test, preprocessors = []) => {
const use = [
require.resolve('mini-css-extract-plugin').loader,
{
loader: require.resolve('mini-css-extract-plugin').loader,
options: {
// only enable hot in development
hmr:
process.env.WEBPACK_DEV_SERVER &&
process.env.WEBPACK_DEV_SERVER !== 'undefined' &&
devServer.hmr,
// if hmr does not work, this is a forceful method.
reloadAll: true
}
},
{
loader: require.resolve('css-loader'),
options: {
Expand Down
12 changes: 0 additions & 12 deletions test/configuration_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -95,16 +95,4 @@ def test_compile?
assert Webpacker.config.compile?
end
end

def test_extract_css?
assert @config.extract_css?

with_rails_env("development") do
refute Webpacker.config.extract_css?
end

with_rails_env("test") do
refute Webpacker.config.extract_css?
end
end
end
Loading